Skip to content

Commit

Permalink
Merge pull request #86 from Salesforce-org-Impact-Labs/distance
Browse files Browse the repository at this point in the history
Distance
  • Loading branch information
mshanemc authored Jun 30, 2020
2 parents 0167810 + 2452f1d commit cdf30ac
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 65 deletions.
3 changes: 3 additions & 0 deletions .forceignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

package.xml
Profile
Profile:Admin
Admin Profile.profile
**profile

# LWC configuration files
**/jsconfig.json
Expand Down
105 changes: 56 additions & 49 deletions force-app/main/default/classes/Scoring.cls
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,8 @@ public with sharing class Scoring {
// example metric: my referrals
// myReferralsPercentile: service referrals / (orgMax - orgMin)

// example metric: Preferred
// true = 100, false = 0

// Negative Weights

// example metric: Distance
// distancePercential: service distance / (orgMax - orgMin) from CMDT

// example metric: service-level-hides
// hidesPercentile = service hides / (orgMax - orgMin)

Expand Down Expand Up @@ -52,7 +46,7 @@ public with sharing class Scoring {
Weighting__c
FROM Scoring_Metric__mdt
WHERE
Weighting__c > 0
Weighting__c != 0
AND Org_Level__c = true
AND Org_Minimum__c != null
AND Org_Maximum__c != null
Expand All @@ -61,25 +55,36 @@ public with sharing class Scoring {
for (Scoring_Metric__mdt metricIterator : metrics) {
weightTotal = weightTotal + metricIterator.Weighting__c;
}
// query CMDT for the metrics

for (Scoring_Metric__mdt metricIterator : metrics) {
map<id, AggregateResult> queryResults = new Map<id, AggregateResult>();
//for each metric, get the stat for relevant services
map<id, AggregateResult> results = new Map<id, AggregateResult>(
(list<AggregateResult>) database.query(
metricIterator.Service_Level_SOQL_Query__c
)
);
if (metricIterator.Service_Level_SOQL_Query__c != null) {
queryResults = new Map<id, AggregateResult>(
(list<AggregateResult>) database.query(
metricIterator.Service_Level_SOQL_Query__c
)
);
}
decimal serviceValue;
decimal spread =
metricIterator.Org_Maximum__c - metricIterator.Org_Minimum__c;
// we'll not assign any points if there is nothing to base it on
if (spread != 0) {
// do a percentile-based conversion for each metric
for (ServiceRecommendation rec : recs) {
AggregateResult result = results.get(rec.ServiceId);
AggregateResult result = queryResults.get(rec.ServiceId);
if (result != null) {
decimal serviceValue = (decimal) result.get('metric');
// create and calculate the new indicator
// the result was found from the aggregateQuery
serviceValue = (decimal) result.get('metric');
} else if (rec.getValue(metricIterator.Label) != null) {
// the metric has a matching property on the ServiceRecommendationObject (ex: Distance) that is populated
serviceValue = (decimal) rec.getValue(metricIterator.Label);
} else {
continue;
}
if (serviceValue != null) {
// still here? we must have a service value. Create and calculate the new indicator
ServiceRecommendation.Indicator indicator = new ServiceRecommendation.Indicator();
indicator.IndicatorType = metricIterator.Label;
// base percentile * this metric's share of the total weight
Expand Down Expand Up @@ -113,42 +118,44 @@ public with sharing class Scoring {
NamespacePrefix,
DeveloperName
FROM Scoring_Metric__mdt
WHERE Weighting__c > 0
WHERE Weighting__c != 0
]) {
list<AggregateResult> results = database.query(
metricIterator.Org_SOQL_Query__c
);
// default order is ASC, so [0] is min and last is max
if (!results.isEmpty()) {
// container for the updates
Metadata.DeployContainer mdContainer = new Metadata.DeployContainer();

Metadata.CustomMetadata recordToUpdate = new Metadata.CustomMetadata();
recordToUpdate.fullName =
'Scoring_Metric.' + metricIterator.DeveloperName;
recordToUpdate.label = metricIterator.DeveloperName;

Metadata.CustomMetadataValue orgMin = new Metadata.CustomMetadataValue();
orgMin.field = 'Org_Minimum__c';
orgMin.value = (decimal) results[0].get('metric');
if (orgMin.value == null) {
orgMin.value = 0;
}
recordToUpdate.values.add(orgMin);
if (metricIterator.Org_SOQL_Query__c != null) {
list<AggregateResult> results = database.query(
metricIterator.Org_SOQL_Query__c
);
// default order is ASC, so [0] is min and last is max
if (!results.isEmpty()) {
// container for the updates
Metadata.DeployContainer mdContainer = new Metadata.DeployContainer();

Metadata.CustomMetadata recordToUpdate = new Metadata.CustomMetadata();
recordToUpdate.fullName =
'Scoring_Metric.' + metricIterator.DeveloperName;
recordToUpdate.label = metricIterator.DeveloperName;

Metadata.CustomMetadataValue orgMin = new Metadata.CustomMetadataValue();
orgMin.field = 'Org_Minimum__c';
orgMin.value = (decimal) results[0].get('metric');
if (orgMin.value == null) {
orgMin.value = 0;
}
recordToUpdate.values.add(orgMin);

Metadata.CustomMetadataValue orgMax = new Metadata.CustomMetadataValue();
orgMax.field = 'Org_Maximum__c';
orgMax.value = (decimal) results[results.size() - 1].get('metric');
if (orgMax.value == null) {
orgMax.value = 0;
}
recordToUpdate.values.add(orgMax);
Metadata.CustomMetadataValue orgMax = new Metadata.CustomMetadataValue();
orgMax.field = 'Org_Maximum__c';
orgMax.value = (decimal) results[results.size() - 1].get('metric');
if (orgMax.value == null) {
orgMax.value = 0;
}
recordToUpdate.values.add(orgMax);

mdContainer.addMetadata(recordToUpdate);
// apply the update, but not during tests
CustomMetadataCallback callback = new customMetadataCallback();
if (!Test.isRunningTest()) {
Metadata.Operations.enqueueDeployment(mdContainer, callback);
mdContainer.addMetadata(recordToUpdate);
// apply the update, but not during tests
CustomMetadataCallback callback = new customMetadataCallback();
if (!Test.isRunningTest()) {
Metadata.Operations.enqueueDeployment(mdContainer, callback);
}
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions force-app/main/default/classes/ServiceRecommendation.cls
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
public class ServiceRecommendation {
@AuraEnabled
public Service__c Service { get; set; }

@AuraEnabled
public Decimal Relevance { get; set; }

Expand Down Expand Up @@ -35,6 +38,9 @@ public class ServiceRecommendation {
@AuraEnabled
public Decimal Rating { get; set; }

@AuraEnabled
public Decimal Distance { get; set; }

@AuraEnabled
public List<Comment> Comments { get; set; }

Expand All @@ -44,9 +50,26 @@ public class ServiceRecommendation {
@AuraEnabled
public Integer totalRatings { get; set; }

@AuraEnabled
public Integer Preferred { get; set; }

@AuraEnabled
public List<Indicator> Indicators { get; set; }

// dynamic getter for supporting returning certain properties
public Decimal getValue(string property) {
if (property == 'Distance') {
return this.Distance;
}
if (property == 'Rating') {
return this.Rating;
}
if (property == 'Preferred') {
return this.Preferred;
}
return null;
}

public class Indicator {
@AuraEnabled
public String IndicatorType { get; set; }
Expand Down
11 changes: 9 additions & 2 deletions force-app/main/default/classes/Test_getRecommendations.cls
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,28 @@ public with sharing class Test_getRecommendations {
);
System.assert(recs[goodServiceIndex].Relevance >= 0);
System.assert(recs[goodServiceIndex].Relevance <= 100);
System.assert(recs[goodServiceIndex].Distance >= 0);
System.assertEquals(1, recs[goodServiceIndex].Preferred);

System.assertEquals(1, recs[goodServiceIndex].Comments.size());
System.assertEquals(
'It is great',
recs[goodServiceIndex].Comments[0].CommentText
);
// check for preferred factor
boolean DistanceMetricExists = false;
for (
ServiceRecommendation.Indicator indicator : recs[goodServiceIndex]
.Indicators
) {
if (indicator.IndicatorType == 'Preferred Service') {
system.assertEquals('TRUE', indicator.IndicatorValue);
if (indicator.IndicatorType == 'Distance') {
DistanceMetricExists = true;
}
if (indicator.IndicatorType == 'Preferred') {
system.assertEquals('1', indicator.IndicatorValue);
}
}
// system.assert(DistanceMetricExists);
}

static testMethod void omitsTeenService() {
Expand Down
19 changes: 11 additions & 8 deletions force-app/main/default/classes/getRecommendations.cls
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,14 @@ public with sharing class getRecommendations {
Type__c,
Website__c,
Zip_Code__c,
Preferred__c
Preferred__c,
DISTANCE(
Location__c,
GEOLOCATION(:client.Location__Latitude__s,
:client.Location__Longitude__s
),
'mi'
) dist
FROM Service__c
WHERE
(Minimum_Age__c = null
Expand All @@ -66,6 +73,8 @@ public with sharing class getRecommendations {
List<ServiceRecommendation> output = new List<ServiceRecommendation>();
for (Service__c service : services) {
ServiceRecommendation SR = new ServiceRecommendation();
SR.Service = service;
SR.Distance = (decimal)service.get('dist');
SR.Relevance = 0;
SR.ServiceId = service.Id;
SR.ProviderName = service.Account__r.Name;
Expand All @@ -81,13 +90,7 @@ public with sharing class getRecommendations {
SR.totalRatings = 0;
SR.Indicators = new List<ServiceRecommendation.Indicator>();
SR.Comments = new List<ServiceRecommendation.Comment>();

if (service.Preferred__c) {
ServiceRecommendation.Indicator indicator = new ServiceRecommendation.Indicator();
indicator.IndicatorType = 'Preferred Service';
indicator.IndicatorValue = 'TRUE';
SR.Indicators.add(indicator);
}
SR.Preferred = service.Preferred__c ? 1 : 0; //translate checkbox to 1,0 value
output.add(SR);
}
return output;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomMetadata xmlns="http://soap.sforce.com/2006/04/metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<label>Distance</label>
<protected>false</protected>
<values>
<field>Based_on_Service_Field__c</field>
<value xsi:type="xsd:boolean">false</value>
</values>
<values>
<field>Calculate_User_Level__c</field>
<value xsi:type="xsd:boolean">false</value>
</values>
<values>
<field>Description__c</field>
<value xsi:type="xsd:string">Weighting based on how far the service is from the client/default location.</value>
</values>
<values>
<field>Org_Level__c</field>
<value xsi:type="xsd:boolean">true</value>
</values>
<values>
<field>Org_Maximum__c</field>
<value xsi:type="xsd:double">25.0</value>
</values>
<values>
<field>Org_Minimum__c</field>
<value xsi:type="xsd:double">0.0</value>
</values>
<values>
<field>Org_SOQL_Query__c</field>
<value xsi:nil="true" />
</values>
<values>
<field>Service_Level_SOQL_Query__c</field>
<value xsi:nil="true" />
</values>
<values>
<field>User_ID__c</field>
<value xsi:nil="true" />
</values>
<values>
<field>Weighting__c</field>
<value xsi:type="xsd:double">-2.0</value>
</values>
</CustomMetadata>
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomMetadata xmlns="http://soap.sforce.com/2006/04/metadata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<label>IsPreferred</label>
<protected>false</protected>
<values>
<field>Based_on_Service_Field__c</field>
<value xsi:type="xsd:boolean">false</value>
</values>
<values>
<field>Calculate_User_Level__c</field>
<value xsi:type="xsd:boolean">false</value>
</values>
<values>
<field>Description__c</field>
<value xsi:type="xsd:string">Services with the Preferred Checkbox are boosted higher in the ranking</value>
</values>
<values>
<field>Org_Level__c</field>
<value xsi:type="xsd:boolean">true</value>
</values>
<values>
<field>Org_Maximum__c</field>
<value xsi:type="xsd:double">0.0</value>
</values>
<values>
<field>Org_Minimum__c</field>
<value xsi:type="xsd:double">1.0</value>
</values>
<values>
<field>Org_SOQL_Query__c</field>
<value xsi:nil="true"/>
</values>
<values>
<field>Service_Level_SOQL_Query__c</field>
<value xsi:nil="true"/>
</values>
<values>
<field>User_ID__c</field>
<value xsi:nil="true"/>
</values>
<values>
<field>Weighting__c</field>
<value xsi:type="xsd:double">1.0</value>
</values>
</CustomMetadata>
7 changes: 5 additions & 2 deletions orgs/beta.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"orgName": "01HousingandHomelessness - Beta Test Org",
"adminEmail": "[email protected]",

"edition": "Developer",
"settings": {
"lightningExperienceSettings": {
Expand All @@ -16,5 +18,6 @@
"sessionSettings": {
"forceRelogin": false
}
} }
}
}
}
}
3 changes: 2 additions & 1 deletion orgs/dev.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"orgName": "01HousingandHomelessness - Dev Org",
"adminEmail": "[email protected]",
"edition": "Developer",
"settings": {
"lightningExperienceSettings": {
Expand All @@ -21,4 +22,4 @@
"enableTranslationWorkbench": true
}
}
}
}
Loading

0 comments on commit cdf30ac

Please sign in to comment.