Skip to content

Commit ebb95e7

Browse files
Merge pull request #366 from AmericaSCORESBayArea/sandbox
Enhance Task Filtering and Responses; Add Coach Stats Endpoint
2 parents 0f8aabe + 675a3dd commit ebb95e7

File tree

5 files changed

+455
-36
lines changed

5 files changed

+455
-36
lines changed

docs/Scores - Salesforce Data API.postman_collection.json

Lines changed: 105 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"info": {
3-
"_postman_id": "0e927c57-e663-43d7-b54f-7487525e3134",
3+
"_postman_id": "43dbedd3-7e21-463c-8cf4-f199f2aa4f83",
44
"name": "Scores - Salesforce Data API",
55
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
66
"_exporter_id": "34720049"
@@ -2009,6 +2009,55 @@
20092009
},
20102010
"response": []
20112011
},
2012+
{
2013+
"name": "/coach/{coachId}/stats",
2014+
"request": {
2015+
"method": "GET",
2016+
"header": [
2017+
{
2018+
"key": "client_id",
2019+
"value": "{{sandbox_client_id}}"
2020+
},
2021+
{
2022+
"key": "client_secret",
2023+
"value": "{{sandbox_client_secret}}"
2024+
},
2025+
{
2026+
"key": "Origin",
2027+
"value": "Postman",
2028+
"type": "text"
2029+
}
2030+
],
2031+
"url": {
2032+
"raw": "{{base_url}}/coach/003cX000005TYcvQAG/stats?interval&teamSeasonId&seasonid",
2033+
"host": [
2034+
"{{base_url}}"
2035+
],
2036+
"path": [
2037+
"coach",
2038+
"003cX000005TYcvQAG",
2039+
"stats"
2040+
],
2041+
"query": [
2042+
{
2043+
"key": "interval",
2044+
"value": null,
2045+
"description": "overall (default) | year | quarter | month | week"
2046+
},
2047+
{
2048+
"key": "teamSeasonId",
2049+
"value": null
2050+
},
2051+
{
2052+
"key": "seasonId",
2053+
"value": null
2054+
}
2055+
]
2056+
},
2057+
"description": "Response Example:\n\n{ \"Not Started\": 1, \"Started\": 0, \"Complete\": 41}"
2058+
},
2059+
"response": []
2060+
},
20122061
{
20132062
"name": "/coach/{coachId}/teamseasons/{teamSeasonId}/stats",
20142063
"request": {
@@ -2029,13 +2078,50 @@
20292078
}
20302079
],
20312080
"url": {
2032-
"raw": "{{base_url_s}}/coach/a0qcX000000GEggQAG/003cX000008IZnXQAW/stats",
2081+
"raw": "{{base_url_s}}/coach/a0qcX000000GEggQAG/teamseasons/003cX000008IZnXQAW/stats",
20332082
"host": [
20342083
"{{base_url_s}}"
20352084
],
20362085
"path": [
20372086
"coach",
20382087
"a0qcX000000GEggQAG",
2088+
"teamseasons",
2089+
"003cX000008IZnXQAW",
2090+
"stats"
2091+
]
2092+
},
2093+
"description": "Response Example:\n\n{ \"Not Started\": 1, \"Started\": 0, \"Complete\": 41}"
2094+
},
2095+
"response": []
2096+
},
2097+
{
2098+
"name": "/coach/{coachId}/teamseasons/{teamSeasonId}/stats",
2099+
"request": {
2100+
"method": "GET",
2101+
"header": [
2102+
{
2103+
"key": "client_id",
2104+
"value": "{{sandbox_client_id}}"
2105+
},
2106+
{
2107+
"key": "client_secret",
2108+
"value": "{{sandbox_client_secret}}"
2109+
},
2110+
{
2111+
"key": "Origin",
2112+
"value": "Postman",
2113+
"type": "text"
2114+
}
2115+
],
2116+
"url": {
2117+
"raw": "{{base_url_s}}/coach/a0qcX000000GEggQAG/teamseasons/003cX000008IZnXQAW/stats",
2118+
"host": [
2119+
"{{base_url_s}}"
2120+
],
2121+
"path": [
2122+
"coach",
2123+
"a0qcX000000GEggQAG",
2124+
"teamseasons",
20392125
"003cX000008IZnXQAW",
20402126
"stats"
20412127
]
@@ -2168,7 +2254,7 @@
21682254
}
21692255
},
21702256
"url": {
2171-
"raw": "{{base_url_s}}/tasks?contactId=003cX000008IZnXQAW&sessionId=a0pcX0000008y3pQAA",
2257+
"raw": "{{base_url_s}}/tasks?contactId=003cX000008IZnXQAW&sessionId=a0pcX0000008y3pQAA&teamSeasonId=a0qUQ000003FNvRYAW&seasonId=a0oUQ000001MNBtYAO&startDate=2025-05-03&endDate=2024-05-03",
21722258
"host": [
21732259
"{{base_url_s}}"
21742260
],
@@ -2183,6 +2269,22 @@
21832269
{
21842270
"key": "sessionId",
21852271
"value": "a0pcX0000008y3pQAA"
2272+
},
2273+
{
2274+
"key": "teamSeasonId",
2275+
"value": "a0qUQ000003FNvRYAW"
2276+
},
2277+
{
2278+
"key": "seasonId",
2279+
"value": "a0oUQ000001MNBtYAO"
2280+
},
2281+
{
2282+
"key": "startDate",
2283+
"value": "2025-05-03"
2284+
},
2285+
{
2286+
"key": "endDate",
2287+
"value": "2024-05-03"
21862288
}
21872289
]
21882290
},

src/main/mule/coach.xml

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,162 @@ output application/json
13581358
}]]></ee:set-payload>
13591359
</ee:message>
13601360
</ee:transform>
1361+
</flow>
1362+
<flow name="get:\coach\(coachId)\stats" doc:id="ffd9b198-afcf-48f3-9378-d284e6a8290f" >
1363+
<set-variable value="#[attributes.uriParams.'coachId']" doc:name='Save "coachId"' doc:id="741cebb4-072d-4d8e-9af8-7bcf4bb79e4e" variableName="coachId" />
1364+
<set-variable value="#[attributes.queryParams.'interval' default &quot;overall&quot;]" doc:name='Save "interval"' doc:id="9c99f9b4-5bd8-4801-b234-db24ca47c389" variableName="interval" />
1365+
<set-variable value="#[attributes.queryParams.'teamSeasonId']" doc:name='Save "teamSeasonId"' doc:id="e219a9fd-c2c6-47ed-851d-39b229927b1a" variableName="teamSeasonId" />
1366+
<set-variable value="#[attributes.queryParams.'seasonId']" doc:name='Save "seasonId"' doc:id="0bab0beb-a972-4a89-b6e2-ba31b3902cf7" variableName="seasonId" />
1367+
<choice doc:name="Choice" doc:id="c26ef9b8-ee01-4386-b285-b20f62423ff7">
1368+
<when expression="#[vars.interval != 'overall']">
1369+
<set-variable value='#[%dw 2.0&#10;import * from dw::core::Dates&#10;import floor from dw::core::Numbers&#10;&#10;output application/json&#10;&#10;var interval = vars.interval&#10;var today = now() as Date&#10;&#10;fun quarterStart(d: Date): Date =&#10; date({&#10; year: d.year,&#10; month: floor(((d.month) - 1) / 3) * 3 + 1,&#10; day: 1&#10; })&#10;&#10;var first =&#10; if (interval == "month") atBeginningOfMonth(today)&#10; else if (interval == "quarter") quarterStart(today)&#10; else if (interval == "year") atBeginningOfYear(today)&#10; else if (interval == "week") atBeginningOfWeek(today)&#10; else today&#10;&#10;var last =&#10; if (interval == "month") (atBeginningOfMonth(today + |P1M|) - |P1D|) as Date&#10; else if (interval == "quarter") (quarterStart(today + |P3M|) - |P1D|) as Date&#10; else if (interval == "year") (atBeginningOfYear(today + |P1Y|) - |P1D|) as Date&#10; else if (interval == "week") (atBeginningOfWeek(today + |P7D|) - |P1D|) as Date&#10; else today&#10;&#10;---&#10;{&#10; firstDay: first,&#10; lastDay : last&#10;}]' doc:name="Set Dates" doc:id="e6d6fe3e-ed67-4f99-941b-19027f57b0ee" variableName="dates" />
1370+
</when>
1371+
</choice>
1372+
<set-variable doc:name="query" doc:id="b267385d-523f-491d-97cf-9fbb7109d686" variableName="query" value="#[%dw 2.0&#10;import * from dw::core::Dates&#10;import floor from dw::core::Numbers&#10;&#10;output application/json&#10;&#10;var firstDay = vars.dates.firstDay default &quot;&quot;&#10;var lastDay = vars.dates.lastDay default &quot;&quot;&#10;var interval = vars.interval&#10;var teamSeasonId = vars.teamSeasonId&#10;var seasonId = vars.seasonId&#10;&#10;&#10;var tq1 = if (interval == 'overall') &quot;&quot; else &#10;&quot;Session__r.Session_Date__c &gt;= $(firstDay) AND Session__r.Session_Date__c &lt;= $(lastDay)&quot;&#10;var tq2 = if (isEmpty(teamSeasonId)) &quot;&quot; else &#10;&quot;Session__r.Team_Season__c = '$(teamSeasonId)'&quot; &#10;var tq3 = if (isEmpty(seasonId)) &quot;&quot; else &#10;&quot;Session__r.Team_Season__r.Season__c = '$(seasonId)'&quot; &#10;var taskQuery = ([tq1, tq2, tq3] filter (item) -&gt; item != &quot;&quot;) joinBy &quot; AND &quot;&#10;&#10;var sq1 = if (interval == 'overall') &quot;&quot; else &#10;&quot;Session_Date__c &gt;= $(firstDay) AND Session_Date__c &lt;= $(lastDay)&quot;&#10;var sq2 = if (isEmpty(teamSeasonId)) &quot;&quot; else &#10;&quot;Team_Season__c = '$(teamSeasonId)'&quot; &#10;var sq3 = if (isEmpty(seasonId)) &quot;&quot; else &#10;&quot;Team_Season__r.Season__c = '$(seasonId)'&quot; &#10;var sessionQuery = ([sq1, sq2, sq3] filter (item) -&gt; item != &quot;&quot;) joinBy &quot; AND &quot;&#10;&#10;&#10;var attendanceQuery = taskQuery&#10;&#10;&#10;---&#10;{&#10; &quot;tasksQuery&quot;: taskQuery,&#10; &quot;sessionsQuery&quot;: sessionQuery,&#10; &quot;attendancesQuery&quot;: attendanceQuery&#10;}]"/>
1373+
<salesforce:query doc:name="Attendances" doc:id="a8fac832-eb95-4309-aecf-9be8eeb63cb4" config-ref="Salesforce_Config" target="attendances">
1374+
<salesforce:salesforce-query><![CDATA[SELECT COUNT()
1375+
FROM Attendance__c
1376+
WHERE (Session__r.Team_Season__r.Coach_Writing__c = ':coachId' OR Session__r.Team_Season__r.Coach_Soccer__c = ':coachId')
1377+
:q]]></salesforce:salesforce-query>
1378+
<salesforce:parameters><![CDATA[#[%dw 2.0
1379+
output application/java
1380+
---
1381+
{
1382+
coachId: vars.coachId,
1383+
q: if (isEmpty((vars.query.attendancesQuery default "") as String))
1384+
""
1385+
else
1386+
" AND " ++ (vars.query.attendancesQuery default "") as String
1387+
}]]]></salesforce:parameters>
1388+
</salesforce:query>
1389+
<salesforce:query doc:name='Attendances "True"' doc:id="13ddeea7-b74c-4a82-99ef-f2a49c53aab8" config-ref="Salesforce_Config" target="attendancesTrue">
1390+
<salesforce:salesforce-query><![CDATA[SELECT COUNT()
1391+
FROM Attendance__c
1392+
WHERE (Session__r.Team_Season__r.Coach_Writing__c = ':coachId' OR Session__r.Team_Season__r.Coach_Soccer__c = ':coachId')
1393+
AND Attended__c = true
1394+
:q]]></salesforce:salesforce-query>
1395+
<salesforce:parameters><![CDATA[#[%dw 2.0
1396+
output application/java
1397+
---
1398+
{
1399+
coachId: vars.coachId,
1400+
q: if (isEmpty((vars.query.attendancesQuery default "") as String))
1401+
""
1402+
else
1403+
" AND " ++ (vars.query.attendancesQuery default "") as String
1404+
}]]]></salesforce:parameters>
1405+
</salesforce:query>
1406+
<salesforce:query doc:name="Sessions" doc:id="98be4b7b-ed86-4faa-afe2-8036661a4047" config-ref="Salesforce_Config" target="sessions">
1407+
<salesforce:salesforce-query><![CDATA[SELECT COUNT()
1408+
FROM Session__c
1409+
WHERE (Team_Season__r.Coach_Writing__c = ':coachId' OR Team_Season__r.Coach_Soccer__c = ':coachId')
1410+
:q]]></salesforce:salesforce-query>
1411+
<salesforce:parameters><![CDATA[#[%dw 2.0
1412+
output application/java
1413+
---
1414+
{
1415+
coachId: vars.coachId,
1416+
q: if (isEmpty((vars.query.sessionsQuery default "") as String))
1417+
""
1418+
else
1419+
" AND " ++ (vars.query.sessionsQuery default "") as String
1420+
}]]]></salesforce:parameters>
1421+
</salesforce:query>
1422+
<salesforce:query doc:name='Sessions "Completed"' doc:id="fff15502-7569-4860-a491-a9237522b7d9" config-ref="Salesforce_Config" target="sessionsCompleted">
1423+
<salesforce:salesforce-query><![CDATA[SELECT COUNT()
1424+
FROM Session__c
1425+
WHERE (Team_Season__r.Coach_Writing__c = ':coachId' OR Team_Season__r.Coach_Soccer__c = ':coachId')
1426+
:subquery
1427+
:q]]></salesforce:salesforce-query>
1428+
<salesforce:parameters><![CDATA[#[%dw 2.0
1429+
import * from dw::core::Dates // atBeginningOfDay, etc. (not used here)
1430+
1431+
var dateTime = now() >> "America/Los_Angeles"
1432+
var nowDate = (dateTime as Date) as String
1433+
var nowTime = dateTime as String { format: "HH:mm:ss" } ++ 'Z'
1434+
1435+
output application/java
1436+
---
1437+
{
1438+
coachId: vars.coachId,
1439+
subquery: " AND Session_Date__c <= $(nowDate) AND Session_End__c <= $(nowTime)",
1440+
q: if (isEmpty((vars.query.sessionsQuery default "") as String))
1441+
""
1442+
else
1443+
" AND " ++ (vars.query.sessionsQuery default "") as String
1444+
}]]]></salesforce:parameters>
1445+
</salesforce:query>
1446+
<salesforce:query doc:name="Tasks" doc:id="34d761e8-bdca-46bd-b7ee-5b915c82f688" config-ref="Salesforce_Config" target="tasks">
1447+
<salesforce:salesforce-query><![CDATA[SELECT COUNT()
1448+
FROM SCORES_Task__c
1449+
WHERE Assigned_To__c = ':coachId'
1450+
:q]]></salesforce:salesforce-query>
1451+
<salesforce:parameters><![CDATA[#[%dw 2.0
1452+
output application/java
1453+
---
1454+
{
1455+
coachId: vars.coachId,
1456+
q: if (isEmpty((vars.query.tasksQuery default "") as String))
1457+
""
1458+
else
1459+
" AND " ++ (vars.query.tasksQuery default "") as String
1460+
}]]]></salesforce:parameters>
1461+
</salesforce:query>
1462+
<salesforce:query doc:name='Tasks "Done"' doc:id="6087d402-6845-4c26-b01f-19513c816964" config-ref="Salesforce_Config" target="tasksDone">
1463+
<salesforce:salesforce-query><![CDATA[SELECT COUNT()
1464+
FROM SCORES_Task__c
1465+
WHERE Assigned_To__c = ':coachId'
1466+
AND Task_Status__c = 'Done'
1467+
:q]]></salesforce:salesforce-query>
1468+
<salesforce:parameters><![CDATA[#[%dw 2.0
1469+
output application/java
1470+
---
1471+
{
1472+
coachId: vars.coachId,
1473+
q: if (isEmpty((vars.query.tasksQuery default "") as String))
1474+
""
1475+
else
1476+
" AND " ++ (vars.query.tasksQuery default "") as String
1477+
}]]]></salesforce:parameters>
1478+
</salesforce:query>
1479+
<ee:transform doc:name="Prepare Response" doc:id="e67b671b-2a19-4189-884f-ce588b0fa2d3">
1480+
<ee:message>
1481+
<ee:set-payload><![CDATA[%dw 2.0
1482+
1483+
fun ratio(trueList = [], totalList = []): String =
1484+
if (sizeOf(totalList default []) != 0)
1485+
((sizeOf(trueList default []) as Number
1486+
/ sizeOf(totalList default []) ) * 100)
1487+
as String { format: "##0.00", roundMode: "HALF_UP" } ++ "%"
1488+
else "100%"
1489+
1490+
1491+
output application/json
1492+
---
1493+
{
1494+
"coach": vars.coachId,
1495+
"interval": vars.interval,
1496+
"teamseason": vars.teamSeasonId default "",
1497+
"season": vars.seasonId default "",
1498+
"sessions": {
1499+
"completed": sizeOf(vars.sessionsCompleted default []),
1500+
"total": sizeOf(vars.sessions default []),
1501+
"ratio": ratio(vars.sessionsCompleted, vars.sessions)
1502+
},
1503+
"tasks": {
1504+
"done": sizeOf(vars.tasksDone default []),
1505+
"total": sizeOf(vars.tasks default []),
1506+
"ratio": ratio(vars.tasksDone, vars.tasks)
1507+
},
1508+
"attendances":{
1509+
"true": sizeOf(vars.attendancesTrue default []),
1510+
"total": sizeOf(vars.attendances default []),
1511+
"ratio": ratio(vars.attendancesTrue, vars.attendances)
1512+
}
1513+
}
1514+
]]></ee:set-payload>
1515+
</ee:message>
1516+
</ee:transform>
13611517
</flow>
13621518
<flow name="get:\coach\(coachId)\teamseasons\(teamSeasonId)\stats" doc:id="59de02c6-9de9-4b00-9b6c-f7af6438b90e" >
13631519
<set-variable value="#[attributes.uriParams.'coachId']" doc:name='Save "coachId"' doc:id="66df3a39-36f9-4328-81d5-ed4a29902fb1" variableName="coachId" />

src/main/mule/sessions.xml

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ var attendedTrue = vars.attendanceResponse filter (item, itemIndex) -&gt; (item.
358358
}]' doc:name="Set Attendances `toRemove` and `Ids`" doc:id="803dbfac-430e-491a-9576-ba7644ba9ccd" variableName="attendanceResponsePrepared"/>
359359
<choice doc:name="Choice" doc:id="92f74e31-c84b-4d92-96a8-a54282a8f912">
360360
<when expression="#[isEmpty(vars.assesmentResponse) and vars.attendanceResponsePrepared.toRemove]">
361-
<ee:transform doc:name="tasksIds + attendancesIds + sessionId" doc:id="0fbc4a8b-63a7-4921-a442-cb27583294c7">
361+
<ee:transform doc:name="tasksIds + attendancesIds + sessionId" doc:id="0fbc4a8b-63a7-4921-a442-cb27583294c7">
362362
<ee:message>
363363
<ee:set-payload><![CDATA[%dw 2.0
364364
output application/java
@@ -378,9 +378,30 @@ payload]]></ee:set-payload>
378378
</ee:transform>
379379
<choice doc:name="Update successful?" doc:id="57cfc27f-d39b-489a-a941-195e88648fa2" >
380380
<when expression="#[payload.successful == false]" >
381-
<set-variable value="#['SALESFORCE_SESSION_CREATE:' ++ (payload.items[0].statusCode default 'UNKNOWN')]" doc:name="Set Custom Error Type" doc:id="599e729e-d7a1-4679-91a0-694cf584353c" variableName="errorCustomType" />
382-
<set-variable value="#[payload.items[0].message default 'Unknown Error']" doc:name="Set Custom Error Message" doc:id="cb64c6a4-6537-4a20-a9ad-fb2248e6bb68" variableName="errorCustomMessage" />
383-
<raise-error doc:name="Raise error" doc:id="d432f898-eca8-410d-b79b-50cf1dffbd6f" type="CUSTOM:CUSTOM_ERROR" description="Something went wrong while creating a session record." />
381+
<set-variable value='#[%dw 2.0&#10;output application/json&#10;&#10;var errors = payload.items filter (item) -&gt; (item.payload.success == false)&#10;var filtered_errors = errors filter (item) -&gt; !(errors[0].exception.message contains ("ENTITY_IS_DELETED"))&#10;&#10;---&#10;sizeOf(filtered_errors) == 0]' doc:name="All Errors Says That The Entity Was Deleted Before?" doc:id="879368d7-0170-4294-bfcc-172da507083d" variableName="deletedBefore"/>
382+
<choice doc:name="Choice" doc:id="0443b0fe-9fad-4636-a8fc-3d6d8c26f2e8">
383+
<when expression="#[vars.deletedBefore]">
384+
<ee:transform doc:name="Success Response" doc:id="24d1ad1d-6e15-4394-a416-69201a784f68" >
385+
<ee:message >
386+
<ee:set-payload ><![CDATA[%dw 2.0
387+
output application/json
388+
---
389+
{
390+
"message" : "Session, related attendances and tasks are deleted successfully, but some records were delete before",
391+
"sessionId": vars.sessionId,
392+
"attendenceIds": vars.attendanceResponsePrepared.ids,
393+
"taskIds": vars.tasksResponsePrepared.ids,
394+
"success": true
395+
}]]></ee:set-payload>
396+
</ee:message>
397+
</ee:transform>
398+
</when>
399+
<otherwise >
400+
<set-variable value="#['SALESFORCE_SESSION_DELETE:' ++ (payload.items[0].statusCode default 'UNKNOWN')]" doc:name="Set Custom Error Type" doc:id="599e729e-d7a1-4679-91a0-694cf584353c" variableName="errorCustomType" />
401+
<set-variable value="#[payload.items[0].message default 'Unknown Error']" doc:name="Set Custom Error Message" doc:id="cb64c6a4-6537-4a20-a9ad-fb2248e6bb68" variableName="errorCustomMessage" />
402+
<raise-error doc:name="Raise error" doc:id="d432f898-eca8-410d-b79b-50cf1dffbd6f" type="CUSTOM:CUSTOM_ERROR" description="Something went wrong while deleting a session record." />
403+
</otherwise>
404+
</choice>
384405
</when>
385406
<otherwise >
386407
<ee:transform doc:name="Success Response" doc:id="6f9995d5-7f26-43e0-84b5-37947225a965">

0 commit comments

Comments
 (0)