Skip to content

Commit

Permalink
Merge pull request #570 from SalesforceFoundation/feature/238__filter…
Browse files Browse the repository at this point in the history
…-service-participants-on-track-attendance

Filter Service Participants that show up on Track Attendance by status, role and stage
  • Loading branch information
dospromptman committed Feb 15, 2022
2 parents b2ba11b + 8c5cf42 commit b9ebd41
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 28 deletions.
17 changes: 15 additions & 2 deletions force-app/main/default/classes/AttendanceController.cls
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,22 @@ public with sharing class AttendanceController {
private static ServiceDeliveryService service = new ServiceDeliveryService();

@AuraEnabled(cacheable=true)
public static ServiceDeliveryService.Roster generateRoster(Id sessionId) {
public static ServiceDeliveryService.Roster generateRoster(
Id sessionId,
String omittedServiceParticipantStatuses,
String omittedProgramEngagementRoles,
String omittedProgramEngagementStages
) {
try {
return service.generateRoster(sessionId);
ServiceDeliveryService.Filters filters = null;

filters = new ServiceDeliveryService.Filters(
omittedServiceParticipantStatuses,
omittedProgramEngagementRoles,
omittedProgramEngagementStages
);

return service.generateRoster(sessionId, filters);
} catch (Exception ex) {
throw Util.getAuraHandledException(ex);
}
Expand Down
27 changes: 21 additions & 6 deletions force-app/main/default/classes/AttendanceController_TEST.cls
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,43 @@ public with sharing class AttendanceController_TEST {
null,
serviceDeliveriesToReturn
);
serviceStub.withReturnValue(generateRoster, Id.class, rosterToReturn);
serviceStub.withReturnValue(
generateRoster,
new List<Type>{ Id.class, ServiceDeliveryService.Filters.class },
rosterToReturn
);
Id sessionId = TestUtil.mockId(ServiceSession__c.SObjectType);
AttendanceController.service = (ServiceDeliveryService) serviceStub.createMock();

Test.startTest();
System.assert(
serviceDeliveriesToReturn ===
AttendanceController.generateRoster(sessionId).deliveries,
AttendanceController.generateRoster(sessionId, '', '', '').deliveries,
'Expected the controller to return the list returned by the service.'
);
Test.stopTest();

serviceStub.assertCalledWith(generateRoster, Id.class, sessionId);
serviceStub.assertCalledWith(
generateRoster,
new List<Type>{ Id.class, ServiceDeliveryService.Filters.class },
new List<Object>{ sessionId, new ServiceDeliveryService.Filters('', '', '') }
);
}

@IsTest
private static void shouldRethrowExceptionFromService() {
String generateRoster = 'generateRoster';
Id sessionId = TestUtil.mockId(ServiceSession__c.SObjectType);
serviceStub.withThrowException(generateRoster, Id.class);
serviceStub.withThrowException(
generateRoster,
new List<Type>{ Id.class, ServiceDeliveryService.Filters.class }
);
AttendanceController.service = (ServiceDeliveryService) serviceStub.createMock();
Exception actualException;

Test.startTest();
try {
AttendanceController.generateRoster(sessionId);
AttendanceController.generateRoster(sessionId, '', '', '');
} catch (Exception ex) {
actualException = ex;
}
Expand All @@ -56,7 +67,11 @@ public with sharing class AttendanceController_TEST {
'Expected the controller to rethrow the exception from the service.'
);

serviceStub.assertCalledWith(generateRoster, Id.class, sessionId);
serviceStub.assertCalledWith(
generateRoster,
new List<Type>{ Id.class, ServiceDeliveryService.Filters.class },
new List<Object>{ sessionId, new ServiceDeliveryService.Filters('', '', '') }
);
}

@IsTest
Expand Down
7 changes: 5 additions & 2 deletions force-app/main/default/classes/ServiceDeliverySelector.cls
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,12 @@ public with sharing class ServiceDeliverySelector {
Id,
Contact__c,
Contact__r.Name,
Service__c,
ProgramEngagement__c,
Service__r.UnitOfMeasurement__c
ProgramEngagement__r.Stage__c,
ProgramEngagement__r.Role__c,
Service__c,
Service__r.UnitOfMeasurement__c,
Status__c
FROM ServiceParticipant__c
WHERE
ServiceSchedule__c = :scheduleId
Expand Down
100 changes: 90 additions & 10 deletions force-app/main/default/classes/ServiceDeliveryService.cls
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,15 @@ public with sharing class ServiceDeliveryService {
set;
}

public Roster generateRoster(Id sessionId) {
public Roster generateRoster(Id sessionId, ServiceDeliveryService.Filters filters) {
ServiceSession__c session = deliverySelector.getSession(sessionId);
FieldSet fieldSet = getFieldSet(session.ServiceSchedule__c);
List<ServiceDelivery__c> deliveries = createServiceDeliveries(fieldSet, session);

List<ServiceDelivery__c> deliveries = createServiceDeliveries(
fieldSet,
session,
filters
);

return new Roster(
fieldSetService.getFieldSetForLWC(
Expand Down Expand Up @@ -183,9 +188,11 @@ public with sharing class ServiceDeliveryService {

private List<ServiceDelivery__c> createServiceDeliveries(
FieldSet fieldSet,
ServiceSession__c session
ServiceSession__c session,
ServiceDeliveryService.Filters filters
) {
Set<Id> existingClients = new Set<Id>();

List<ServiceDelivery__c> deliveries = new List<ServiceDelivery__c>(
deliverySelector.getServiceDeliveriesBySessionId(fieldSet, session.Id)
);
Expand All @@ -194,13 +201,15 @@ public with sharing class ServiceDeliveryService {
existingClients.add(delivery.Contact__c);
}

for (
ServiceParticipant__c participant : deliverySelector.getServiceParticipantsByScheduleId(
session.ServiceSchedule__c,
existingClients
)
) {
deliveries.add(createServiceDelivery(session, participant));
List<ServiceParticipant__c> participants = deliverySelector.getServiceParticipantsByScheduleId(
session.ServiceSchedule__c,
existingClients
);

for (ServiceParticipant__c participant : participants) {
if (filters == null || filters.shouldInclude(participant)) {
deliveries.add(createServiceDelivery(session, participant));
}
}

return deliveries;
Expand Down Expand Up @@ -270,6 +279,77 @@ public with sharing class ServiceDeliveryService {
}
}

public class Filters {
private Set<String> excludedServiceParticipantStatuses;
private Set<String> excludedProgramEngagementRoles;
private Set<String> excludedProgramEngagementStages;

public Filters(
String omitServiceParticipantStatuses,
String omitProgramEngagementRoles,
String omitProgramEngagementStages
) {
List<String> spStatuses = omitServiceParticipantStatuses.split(',');
List<String> peRoles = omitProgramEngagementRoles.split(',');
List<String> peStages = omitProgramEngagementStages.split(',');

for (Integer i = 0; i < spStatuses.size(); i++) {
spStatuses[i] = spStatuses[i].trim().toLowerCase();
}

for (Integer i = 0; i < peRoles.size(); i++) {
peRoles[i] = peRoles[i].trim().toLowerCase();
}

for (Integer i = 0; i < peStages.size(); i++) {
peStages[i] = peStages[i].trim().toLowerCase();
}

setFilters(
new Set<String>(spStatuses),
new Set<String>(peRoles),
new Set<String>(peStages)
);
}

public Boolean shouldInclude(ServiceParticipant__c participant) {
if (
valueIsFiltered(
excludedServiceParticipantStatuses,
participant.Status__c
) ||
valueIsFiltered(
excludedProgramEngagementRoles,
participant.ProgramEngagement__r.Role__c
) ||
valueIsFiltered(
excludedProgramEngagementStages,
participant.ProgramEngagement__r.Stage__c
)
) {
return false;
}
return true;
}

private Boolean valueIsFiltered(Set<String> filter, String value) {
if (filter != null && filter.size() > 0 && value != null) {
return filter.contains(value.toLowerCase());
}
return false;
}

private void setFilters(
Set<String> excludedServiceParticipantStatuses,
Set<String> excludedProgramEngagementRoles,
Set<String> excludedProgramEngagementStages
) {
this.excludedServiceParticipantStatuses = excludedServiceParticipantStatuses;
this.excludedProgramEngagementRoles = excludedProgramEngagementRoles;
this.excludedProgramEngagementStages = excludedProgramEngagementStages;
}
}

public class ServiceDeliveryException extends Exception {
}
}
53 changes: 47 additions & 6 deletions force-app/main/default/classes/ServiceDeliveryService_TEST.cls
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,45 @@ public with sharing class ServiceDeliveryService_TEST {

private static ServiceDeliveryService service = new ServiceDeliveryService();

@IsTest
private static void shouldFilterParticipants() {
ServiceParticipant__c enrolledParticipant = createMockParticipant();

ServiceDeliveryService.Filters filterOutEnrolled = new ServiceDeliveryService.Filters(
'Enrolled',
'',
''
);

ServiceDeliveryService.Filters filterOutWaitlisted = new ServiceDeliveryService.Filters(
'Waitlisted',
'',
''
);

ServiceDeliveryService.Filters filterOutBoth = new ServiceDeliveryService.Filters(
'waitlisted, ENROLLED',
'',
''
);

System.AssertEquals(
false,
filterOutEnrolled.shouldInclude(enrolledParticipant),
'Enrolled participant should NOT be included by filter excluding enrolled'
);
System.AssertEquals(
true,
filterOutWaitlisted.shouldInclude(enrolledParticipant),
'Enrolled participant SHOULD be included by filter excluding only waitlisted'
);
System.AssertEquals(
false,
filterOutBoth.shouldInclude(enrolledParticipant),
'Enrolled participant should NOT be included by filter excluding both enrolled and waitlisted'
);
}

@IsTest
private static void shouldGetBuckets() {
List<String> bucketNames = new List<String>{ 'Absent', 'Present' };
Expand Down Expand Up @@ -81,7 +120,7 @@ public with sharing class ServiceDeliveryService_TEST {
service.deliverySelector = (ServiceDeliverySelector) deliverySelectorStub.create();

Test.startTest();
service.generateRoster(sessionId);
service.generateRoster(sessionId, null);
Test.stopTest();

deliverySelectorStub.assertCalledAsExpected();
Expand Down Expand Up @@ -118,7 +157,8 @@ public with sharing class ServiceDeliveryService_TEST {
Test.startTest();
System.assertEquals(
deliveriesToReturn,
service.generateRoster(deliveriesToReturn[0].ServiceSession__c).deliveries,
service.generateRoster(deliveriesToReturn[0].ServiceSession__c, null)
.deliveries,
'Expected only the service deliveries returned by the selector.'
);
Test.stopTest();
Expand Down Expand Up @@ -160,7 +200,7 @@ public with sharing class ServiceDeliveryService_TEST {
service.deliverySelector = (ServiceDeliverySelector) deliverySelectorStub.create();

Test.startTest();
actualDeliveries = service.generateRoster(sessionId).deliveries;
actualDeliveries = service.generateRoster(sessionId, null).deliveries;
Test.stopTest();

System.assertEquals(
Expand Down Expand Up @@ -228,7 +268,7 @@ public with sharing class ServiceDeliveryService_TEST {
service.deliverySelector = (ServiceDeliverySelector) deliverySelectorStub.create();

Test.startTest();
actualDeliveries = service.generateRoster(sessionId).deliveries;
actualDeliveries = service.generateRoster(sessionId, null).deliveries;
Test.stopTest();

System.assertEquals(
Expand Down Expand Up @@ -344,7 +384,7 @@ public with sharing class ServiceDeliveryService_TEST {
];

Test.startTest();
actualDeliveries = service.generateRoster(session.Id).deliveries;
actualDeliveries = service.generateRoster(session.Id, null).deliveries;
Test.stopTest();

Integer countParticipants = [
Expand Down Expand Up @@ -398,7 +438,8 @@ public with sharing class ServiceDeliveryService_TEST {
return new ServiceParticipant__c(
Id = TestUtil.mockId(ServiceParticipant__c.SObjectType),
Contact__c = TestUtil.mockId(Contact.SObjectType),
ProgramEngagement__c = TestUtil.mockId(ProgramEngagement__c.SObjectType)
ProgramEngagement__c = TestUtil.mockId(ProgramEngagement__c.SObjectType),
Status__c = 'Enrolled'
);
}

Expand Down
25 changes: 24 additions & 1 deletion force-app/main/default/lwc/attendance/attendance.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ const ITEM_PAGE_NAVIGATION_TYPE = "standard__navItemPage";
const ATTENDANCE_TAB = "Attendance";
export default class Attendance extends NavigationMixin(LightningElement) {
@api recordId;
@api omitServiceParticipantStatuses;
@api omitProgramEngagementRoles;
@api omitProgramEngagementStages;

@track serviceDeliveries;
@track fieldSet;

Expand Down Expand Up @@ -144,7 +148,12 @@ export default class Attendance extends NavigationMixin(LightningElement) {
}
}

@wire(generateRoster, { sessionId: "$recordId" })
@wire(generateRoster, {
sessionId: "$recordId",
omittedServiceParticipantStatuses: "$omittedServiceParticipantStatuses",
omittedProgramEngagementRoles: "$omittedProgramEngagementRoles",
omittedProgramEngagementStages: "$omittedProgramEngagementStages",
})
wiredServiceDeliveries(result) {
this.wiredServiceDeliveriesResult = result;
if (!(result.data || result.error)) {
Expand All @@ -170,6 +179,20 @@ export default class Attendance extends NavigationMixin(LightningElement) {
loadStyle(this, pmmFolder + "/attendancePrintOverride.css");
}

get omittedServiceParticipantStatuses() {
return this.omitServiceParticipantStatuses
? this.omitServiceParticipantStatuses
: "";
}

get omittedProgramEngagementRoles() {
return this.omitProgramEngagementRoles ? this.omitProgramEngagementRoles : "";
}

get omittedProgramEngagementStages() {
return this.omitProgramEngagementStages ? this.omitProgramEngagementStages : "";
}

get hasServiceDeliveries() {
return this.serviceDeliveries && this.serviceDeliveries.length;
}
Expand Down
Loading

0 comments on commit b9ebd41

Please sign in to comment.