From 31ae0aa7eaac67a7770e0d7d7f2816f6b4aa5c03 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Tue, 8 Sep 2026 19:35:46 -0400 Subject: [PATCH 01/17] Add app-info.json for Promotion Nomination app --- examples/Promotion_Nomination/app-info.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 examples/Promotion_Nomination/app-info.json diff --git a/examples/Promotion_Nomination/app-info.json b/examples/Promotion_Nomination/app-info.json new file mode 100644 index 0000000..c371409 --- /dev/null +++ b/examples/Promotion_Nomination/app-info.json @@ -0,0 +1,6 @@ +JSON +{ + "title": "Promotion Nomination", + "description": "Workday App for managers to nominate their direct reports for promotions", + "type": "Extend App" +} From 67f59c98ad574c42d22ac2ab50f3c580b5991412 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Tue, 8 Sep 2026 19:39:48 -0400 Subject: [PATCH 02/17] Create .gitkeep --- examples/Promotion_Nomination/model/.gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/Promotion_Nomination/model/.gitkeep diff --git a/examples/Promotion_Nomination/model/.gitkeep b/examples/Promotion_Nomination/model/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/Promotion_Nomination/model/.gitkeep @@ -0,0 +1 @@ + From 961b72ce298f7b259de81efb835e02d4793006e7 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Tue, 8 Sep 2026 19:40:25 -0400 Subject: [PATCH 03/17] Add files via upload --- .../ManagerPromotionNomination.securitydomain | 6 + .../model/NominateEmployee.task | 10 ++ .../PromotionNominationBO.businessobject | 149 ++++++++++++++++++ .../PromotionNominationBP.businessprocess | 25 +++ .../model/PromotionNominations.report | 101 ++++++++++++ 5 files changed, 291 insertions(+) create mode 100644 examples/Promotion_Nomination/model/ManagerPromotionNomination.securitydomain create mode 100644 examples/Promotion_Nomination/model/NominateEmployee.task create mode 100644 examples/Promotion_Nomination/model/PromotionNominationBO.businessobject create mode 100644 examples/Promotion_Nomination/model/PromotionNominationBP.businessprocess create mode 100644 examples/Promotion_Nomination/model/PromotionNominations.report diff --git a/examples/Promotion_Nomination/model/ManagerPromotionNomination.securitydomain b/examples/Promotion_Nomination/model/ManagerPromotionNomination.securitydomain new file mode 100644 index 0000000..ba44c22 --- /dev/null +++ b/examples/Promotion_Nomination/model/ManagerPromotionNomination.securitydomain @@ -0,0 +1,6 @@ +{ + "id": 1, + "name": "ManagerPromotionNomination", + "enabledForPageSecurity": true, + "enabledForOrchestrationSecurity": false +} \ No newline at end of file diff --git a/examples/Promotion_Nomination/model/NominateEmployee.task b/examples/Promotion_Nomination/model/NominateEmployee.task new file mode 100644 index 0000000..e01d788 --- /dev/null +++ b/examples/Promotion_Nomination/model/NominateEmployee.task @@ -0,0 +1,10 @@ +{ + "id": 1, + "name": "NominateEmployee", + "label": "Nominate Employee", + "securityDomains": [ + "ManagerPromotionNomination" + ], + "businessObject": "PromotionNominationBO", + "routePath": "/" +} \ No newline at end of file diff --git a/examples/Promotion_Nomination/model/PromotionNominationBO.businessobject b/examples/Promotion_Nomination/model/PromotionNominationBO.businessobject new file mode 100644 index 0000000..cc34647 --- /dev/null +++ b/examples/Promotion_Nomination/model/PromotionNominationBO.businessobject @@ -0,0 +1,149 @@ +{ + "id": 1, + "name": "PromotionNominationBO", + "label": "Promotion Nomination B O", + "defaultSecurityDomains": [ + "ManagerPromotionNomination" + ], + "defaultCollection": { + "name": "promotionNominationBOS", + "label": "Promotion Nomination B O S" + }, + "fields": [ + { + "enableReportingFromTarget": false, + "secureByTarget": true, + "target": "WORKER", + "isPurgeable": false, + "useForDisplay": false, + "type": "SINGLE_INSTANCE", + "name": "nominee", + "id": 1 + }, + { + "enableReportingFromTarget": false, + "secureByTarget": true, + "target": "WORKER", + "isPurgeable": false, + "useForDisplay": false, + "type": "SINGLE_INSTANCE", + "name": "nominator", + "id": 2 + }, + { + "enableSearch": false, + "enableIndex": false, + "isPurgeable": false, + "useForDisplay": false, + "isReferenceId": false, + "label": "Nomination Reason", + "type": "TEXT", + "name": "nominationReason", + "id": 3 + }, + { + "precision": "DAY", + "enableIndex": false, + "isPurgeable": false, + "type": "DATE", + "name": "proposedDate", + "id": 4 + }, + { + "enableReportingFromTarget": false, + "secureByTarget": false, + "target": "JOB_PROFILE", + "isPurgeable": false, + "useForDisplay": false, + "type": "SINGLE_INSTANCE", + "name": "proposedJobProfile", + "id": 5 + }, + { + "enableSearch": false, + "enableIndex": false, + "isPurgeable": false, + "useForDisplay": false, + "isReferenceId": false, + "type": "TEXT", + "name": "promotionCycle", + "id": 6 + }, + { + "enableSearch": false, + "enableIndex": false, + "isPurgeable": false, + "useForDisplay": false, + "isReferenceId": false, + "type": "TEXT", + "name": "timeInJobProfile", + "id": 7 + }, + { + "precision": "DAY", + "enableIndex": false, + "isPurgeable": false, + "type": "DATE", + "name": "hireDate", + "id": 8 + }, + { + "enableReportingFromTarget": false, + "secureByTarget": false, + "target": "JOB_PROFILE", + "isPurgeable": false, + "useForDisplay": false, + "type": "SINGLE_INSTANCE", + "name": "currentJobProfile", + "id": 9 + }, + { + "enableSearch": false, + "enableIndex": false, + "isPurgeable": false, + "useForDisplay": false, + "isReferenceId": false, + "type": "TEXT", + "name": "currentJobTitle", + "id": 10 + }, + { + "precision": "DAY", + "enableIndex": false, + "isPurgeable": false, + "type": "DATE", + "name": "lastPromotionDate", + "id": 11 + }, + { + "enableSearch": false, + "enableIndex": false, + "isPurgeable": false, + "useForDisplay": false, + "isReferenceId": false, + "type": "TEXT", + "name": "workerConsideration", + "id": 12 + }, + { + "enableSearch": false, + "enableIndex": false, + "isPurgeable": false, + "useForDisplay": false, + "isReferenceId": false, + "type": "TEXT", + "name": "businessNeed", + "id": 13 + }, + { + "enableSearch": false, + "enableIndex": false, + "isPurgeable": false, + "useForDisplay": false, + "isReferenceId": false, + "type": "TEXT", + "name": "workerSuitRole", + "id": 14 + } + ] +} \ No newline at end of file diff --git a/examples/Promotion_Nomination/model/PromotionNominationBP.businessprocess b/examples/Promotion_Nomination/model/PromotionNominationBP.businessprocess new file mode 100644 index 0000000..39dd80a --- /dev/null +++ b/examples/Promotion_Nomination/model/PromotionNominationBP.businessprocess @@ -0,0 +1,25 @@ +{ + "id": 1, + "name": "PromotionNominationBP", + "label": "Promotion Nomination BP", + "description": "Business Process Type for PromotionNominationBP", + "useForOrchestrate": false, + "allowsCancel": true, + "approvalStep": { + "pageRoute": "/eventDetails", + "actions": [ + "APPROVE", + "DENY" + ] + }, + "actionSteps": [], + "targetBusinessObject": "PromotionNominationBO", + "securityDomains": [ + "ManagerPromotionNomination" + ], + "details": { + "pageRoute": "/eventDetails/{eventId}" + }, + "allowsManualSendBack": false, + "allowsRescind": true +} \ No newline at end of file diff --git a/examples/Promotion_Nomination/model/PromotionNominations.report b/examples/Promotion_Nomination/model/PromotionNominations.report new file mode 100644 index 0000000..972caf2 --- /dev/null +++ b/examples/Promotion_Nomination/model/PromotionNominations.report @@ -0,0 +1,101 @@ +{ + "id": 1, + "name": "PromotionNominations", + "businessObject": "PromotionNominationBO", + "defaultSecurityDomains": [ + "ManagerPromotionNomination" + ], + "sortConfigs": [], + "columns": [ + { + "id": 1, + "name": "PromotionNominationBO", + "order": "a", + "isSelfReferencing": true + }, + { + "id": 2, + "name": "Nominee", + "order": "b", + "field": "nominee" + }, + { + "id": 3, + "name": "Nominator", + "order": "c", + "field": "nominator" + }, + { + "id": 4, + "name": "Nomination Reason", + "order": "d", + "field": "nominationReason" + }, + { + "id": 5, + "name": "Proposed Date", + "order": "e", + "field": "proposedDate" + }, + { + "id": 6, + "name": "Proposed Job Profile", + "order": "f", + "field": "proposedJobProfile" + }, + { + "id": 7, + "name": "Promotion Cycle", + "order": "g", + "field": "promotionCycle" + }, + { + "id": 8, + "name": "Time In Job Profile", + "order": "h", + "field": "timeInJobProfile" + }, + { + "id": 9, + "name": "Hire Date", + "order": "i", + "field": "hireDate" + }, + { + "id": 10, + "name": "Current Job Profile", + "order": "j", + "field": "currentJobProfile" + }, + { + "id": 11, + "name": "Current Job Title", + "order": "k", + "field": "currentJobTitle" + }, + { + "id": 12, + "name": "Last Promotion Date", + "order": "l", + "field": "lastPromotionDate" + }, + { + "id": 13, + "name": "Worker Consideration", + "order": "m", + "field": "workerConsideration" + }, + { + "id": 15, + "name": "Worker Suit Role", + "order": "o", + "field": "workerSuitRole" + }, + { + "id": 16, + "name": "Business Need", + "order": "p", + "field": "businessNeed" + } + ] +} \ No newline at end of file From 6be960127d094e045686a72afe40c179b75650a7 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Tue, 8 Sep 2026 19:41:24 -0400 Subject: [PATCH 04/17] Create .gitkeep --- examples/Promotion_Nomination/presentation/.gitkeep | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/Promotion_Nomination/presentation/.gitkeep diff --git a/examples/Promotion_Nomination/presentation/.gitkeep b/examples/Promotion_Nomination/presentation/.gitkeep new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/Promotion_Nomination/presentation/.gitkeep @@ -0,0 +1 @@ + From e1e38e4d6b987ab5d164787c5fcc48e06f695bae Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Tue, 8 Sep 2026 19:42:21 -0400 Subject: [PATCH 05/17] Add files via upload --- .../presentation/eventDetails.pmd | 142 +++++++ .../presentation/managerNomination.pmd | 354 ++++++++++++++++++ .../promotionNomination_rvylxm.amd | 42 +++ .../promotionNomination_rvylxm.smd | 21 ++ 4 files changed, 559 insertions(+) create mode 100644 examples/Promotion_Nomination/presentation/eventDetails.pmd create mode 100644 examples/Promotion_Nomination/presentation/managerNomination.pmd create mode 100644 examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.amd create mode 100644 examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.smd diff --git a/examples/Promotion_Nomination/presentation/eventDetails.pmd b/examples/Promotion_Nomination/presentation/eventDetails.pmd new file mode 100644 index 0000000..4ded9fc --- /dev/null +++ b/examples/Promotion_Nomination/presentation/eventDetails.pmd @@ -0,0 +1,142 @@ +{ + "id": "eventDetails", + "endPoints": [ + { + "name": "eventGenericBP", + "url": "<% 'https://api.workday.com/businessProcess/v1/events/' + queryParams.eventId %>", + "authType": "sso" + }, + { + "name": "getPromotionNominationBP", + "url": "<% 'https://api.workday.com/apps/'+ site.applicationId + '/v1/promotionNominationBOS/' + eventGenericBP.for.id%>", + "authType": "sso", + "httpMethod": "GET" + } + ], + "presentation": { + "title": { + "type": "title", + "label": "View Promotion Nomination Details" + }, + "body": { + "type": "section", + "horizontal": false, + "children": [ + { + "enabled": false, + "type": "text", + "label": "Nominee", + "id": "nomineeWidget", + "value": "<% empty getPromotionNominationBP.nominee.descriptor ? 'No Nominee value found' : getPromotionNominationBP.nominee.descriptor %>" + }, + { + "enabled": false, + "type": "text", + "label": "Nominator", + "id": "nominatorWidget", + "value": "<% empty getPromotionNominationBP.nominator.descriptor ? 'No Nominator value found' : getPromotionNominationBP.nominator.descriptor %>" + }, + { + "type": "fieldSet", + "children": [ + { + "type": "text", + "id": "nominationReasonWidget", + "label": "Nomination Reason", + "value": "<% empty getPromotionNominationBP.nominationReason ? 'No Nominator value found' : getPromotionNominationBP.nominationReason %>" + }, + { + "visible": true, + "type": "date", + "id": "proposedDateWidget", + "label": "Proposed Date", + "value": "<% empty getPromotionNominationBP.proposedDate ? null : getPromotionNominationBP.proposedDate %>" + }, + { + "enabled": false, + "type": "text", + "label": "Proposed Job Profile", + "id": "proposedJobProfileWidget", + "value": "<% empty getPromotionNominationBP.proposedJobProfile.descriptor ? 'No Nominator value found' : getPromotionNominationBP.proposedJobProfile.descriptor %>" + }, + { + "type": "text", + "id": "promotionCycleWidget", + "label": "Promotion Cycle", + "value": "<% empty getPromotionNominationBP.promotionCycle ? 'No Nominator value found' : getPromotionNominationBP.promotionCycle %>" + }, + { + "type": "text", + "id": "timeInJobProfileWidget", + "label": "Time in Job Profile", + "value": "<% empty getPromotionNominationBP.timeInJobProfile ? 'No Nominator value found' : getPromotionNominationBP.timeInJobProfile %>" + }, + { + "type": "date", + "id": "hireDateeWidget", + "label": "Hire Date", + "value": "<% empty getPromotionNominationBP.hireDate ? null : getPromotionNominationBP.hireDate %>" + }, + { + "type": "text", + "id": "currentJobProfileWidget", + "label": "Current Job Profile", + "value": "<% empty getPromotionNominationBP.currentJobProfile.descriptor ? 'No Nominator value found' : getPromotionNominationBP.currentJobProfile.descriptor %>" + }, + { + "type": "text", + "id": "currentJobTitleWidget", + "label": "Current Job Title", + "value": "<% empty getPromotionNominationBP.currentJobTitle ? 'No Nominator value found' : getPromotionNominationBP.currentJobTitle %>" + }, + { + "visible": true, + "type": "date", + "id": "lastPromotionDateWidget", + "label": "Last Promotion Date", + "value": "<% empty getPromotionNominationBP.lastPromotionDate ? null : getPromotionNominationBP.lastPromotionDate %>" + }, + { + "type": "date", + "id": "hireDateWidget", + "label": "Employee Hire Date", + "value": "<% empty getPromotionNominationBP.hireDate ? null : getPromotionNominationBP.hireDate %>" + }, + { + "type": "textArea", + "id": "workerConsiderationWidget", + "label": "Why do you consicder the worker?", + "value": "<% empty getPromotionNominationBP.workerConsideration ? 'No Nominator value found' : getPromotionNominationBP.workerConsideration %>" + }, + { + "type": "textArea", + "id": "businessNeedWidget", + "label": "What is the business need?", + "value": "<% empty getPromotionNominationBP.businessNeed ? 'No Nominator value found' : getPromotionNominationBP.businessNeed %>" + }, + { + "type": "textArea", + "id": "workerSuitRoleWidget", + "label": "Does the Worker suit the role?", + "value": "<% empty getPromotionNominationBP.workerSuitRole ? 'No Nominator value found' : getPromotionNominationBP.workerSuitRole %>" + } + ] + } + ] + }, + "footer": { + "type": "footer", + "children": [ + { + "type": "richText", + "enabled": "false", + "value": "Powered By Workday Extend" + } + ] + }, + "pageType": "VIEW" + }, + "securityDomains": [ + "ManagerPromotionNomination" + ] +} \ No newline at end of file diff --git a/examples/Promotion_Nomination/presentation/managerNomination.pmd b/examples/Promotion_Nomination/presentation/managerNomination.pmd new file mode 100644 index 0000000..e7caec4 --- /dev/null +++ b/examples/Promotion_Nomination/presentation/managerNomination.pmd @@ -0,0 +1,354 @@ +{ + "id": "managerNomination", + "endPoints": [ + { + "name": "me", + "baseUrlType": "workday-staffing", + "url": "/workers/me", + "authType": "sso" + }, + { + "_comment": "Retrieves logged-in manager's direct reports ", + "name": "getEmployeeList", + "baseUrlType": "workday-wql", + "authType": "sso", + "url": "<% + var query= '/data?query=' + string:urlEncode('SELECT worker FROM myDirectReports WHERE workerType in (d588c41a446c11de98360015c5e6daf6)'); + return query; + %>" + }, + { + "name": "workerInfo", + "url": "https://api.workday.com/common/v1/workers/me", + "authType": "sso" + }, + { + "_comment": "Retrieves selected worker information ", + "deferred": true, + "name": "getEmployeeData", + "baseUrlType": "workday-wql", + "authType": "sso", + "url": "<% + var query= '/data?query=' + string:urlEncode('SELECT worker, location, manager_Level01, hireDate, timeInJobProfile, jobProfile, jobTitle, lastPromotionDate FROM myDirectReports WHERE worker in \"' +selectedWorkerIdQuery+ '\"'); + return query; + %>" + }, + { + "name": "getJobProfiles", + "baseUrlType": "workday-wql", + "authType": "sso", + "url": "<% + var query= '/data?query=' + string:urlEncode('SELECT jobProfileName, workdayID FROM allActiveJobProfiles (dataSourceFilter = defaultFilter) WHERE jobProfileName startswith \"' +instanceListQuery+ '\"'); + // console.info('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXz', query); + return query.replace('%2B','%20'); + %>", + "deferred": true + }, + { + "name": "getJobProfilesNoSearch", + "baseUrlType": "workday-wql", + "authType": "sso", + "url": "<% + var query= '/data?query=' + string:urlEncode('SELECT jobProfileName, workdayID FROM allActiveJobProfiles (dataSourceFilter = defaultFilter)'); + // console.info('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXz', query); + return query.replace('%2B','%20'); + %>" + } + ], + "presentation": { + "title": { + "type": "title", + "label": "Employee Promotion Nomination" + }, + "body": { + "type": "fieldSet", + "horizontal": false, + "children": [ + { + "type": "section", + "children": [ + { + "type": "readOnlyText", + "id": "welcome", + "value": "Welcome to the Promotion Nomination App. Please select an employee to begin" + }, + { + "horizontal": true, + "type": "section", + "verticalAlignment": "top", + "children": [ + { + "required": true, + "type": "instanceList", + "label": "Select an Employee", + "id": "selectedEmployeeWidget", + "displayKey": "worker.descriptor", + "idKey": "worker.id", + "values": "<% getEmployeeList.data %>", + "onChange": "<% + if (!empty selectedEmployeeWidget.value[0]) //Retrieve selected employee information + { + + var responseEmpData =getEmployeeData.invoke({'selectedWorkerIdQuery': selectedEmployeeWidget.value[0]}); + + + var timeInJobProfileVar =(!empty responseEmpData.data[0].timeInJobProfile) ? responseEmpData.data[0].timeInJobProfile : null; + var currentJobProfileVar = (!empty responseEmpData.data[0].jobProfile.descriptor) ? responseEmpData.data[0].jobProfile.descriptor: null; + var currentJobProfileIDVar = (!empty responseEmpData.data[0].jobProfile.id) ? responseEmpData.data[0].jobProfile.id: null; + var currentJobProfileResponseValue = [{'id': currentJobProfileIDVar, 'descriptor': currentJobProfileVar}]; + var rawHireDateVar = (!empty responseEmpData.data[0].hireDate) ? responseEmpData.data[0].hireDate: null; + var parsedHireDateVar = date:parse(rawHireDateVar, 'yyyy-MM-dd'); + var jobTitleVar = (!empty responseEmpData.data[0].jobTitle) ? responseEmpData.data[0].jobTitle: null; + var rawLastPromotionDateVar = (!empty responseEmpData.data[0].lastPromotionDate) ? responseEmpData.data[0].lastPromotionDate: null; + var parsedLastPromotionDateVar = date:parse(rawLastPromotionDateVar, 'yyyy-MM-dd'); + + + promotionReasonWidget.visible = true; + proposedDateWidget.visible = true; + proposedDateWidget.visible = true; + proposedJobProfileWidget.visible = true; + promotionCycleWidget.visible = true; + + timeJobProfileWidget.value = timeInJobProfileVar; + timeJobProfileWidget.visible = true; + + currentJobProfileWidget.setValues(currentJobProfileResponseValue); + currentJobProfileWidget.setValue(currentJobProfileResponseValue.map(item => {item.id})); + currentJobProfileWidget.visible = true; + + hireDateWidget.value = parsedHireDateVar; + hireDateWidget.visible = true; + + currentJobTitleWidget.value = jobTitleVar; + currentJobTitleWidget.visible = true; + + lastPromotionDateWidget.value = parsedLastPromotionDateVar; + lastPromotionDateWidget.visible = true; + + promotionConsiderationQ1.visible = true; + promotionBusNeedQ2.visible = true; + roleConsiderationQ3.visible = true; + } + else + { + self.setError('Please select a worker to nominate'); + } %>" + } + ], + "columnWidthRatios": [ + "0.75", + "0.25" + ] + }, + { + "required": true, + "visible": false, + "type": "radioGroup", + "id": "promotionReasonWidget", + "label": "Reason for Promotion", + "instanceList": [ + { + "id": "100A", + "descriptor": "Merit/Performance" + }, + { + "id": "101B", + "descriptor": "Increased Responsibilities" + }, + { + "id": "102C", + "descriptor": "Organizational Restructuring" + } + ] + }, + { + "required": true, + "visible": false, + "label": "Proposed Effective Date", + "type": "date", + "id": "proposedDateWidget" + }, + { + "visible": false, + "label": "Proposed Job Profile", + "type": "instanceList", + "id": "proposedJobProfileWidget", + "values": "<% getJobProfilesNoSearch.data %>", + "displayKey": "jobProfileName", + "idKey": "workdayID" + } + ] + }, + { + "type": "section", + "id": "derivedFieldsSection", + "children": [ + { + "enabled": false, + "visible": false, + "label": "Promotion Cycle", + "type": "text", + "id": "promotionCycleWidget", + "value": "2026-Q1" + }, + { + "enabled": false, + "label": "Current Manager", + "visible": false, + "type": "text", + "id": "currentManagerWidget" + }, + { + "enabled": false, + "label": "Time in Job Profile", + "visible": false, + "type": "text", + "id": "timeJobProfileWidget" + }, + { + "enabled": false, + "label": "Hire Date", + "visible": false, + "type": "date", + "id": "hireDateWidget" + }, + { + "enabled": false, + "visible": false, + "label": "Current Job Profile", + "type": "instanceList", + "idKey": "id", + "id": "currentJobProfileWidget", + "values": "<% [] %>" + }, + { + "enabled": false, + "label": "Current Job Title", + "visible": false, + "type": "text", + "id": "currentJobTitleWidget" + }, + { + "enabled": false, + "label": "Date of Last Promotion", + "visible": false, + "type": "date", + "id": "lastPromotionDateWidget" + }, + { + "required": true, + "visible": false, + "type": "textArea", + "id": "promotionConsiderationQ1", + "label": "Why is the worker being considered?" + }, + { + "required": true, + "visible": false, + "type": "textArea", + "id": "promotionBusNeedQ2", + "label": "What is the business need?" + }, + { + "required": true, + "visible": false, + "type": "textArea", + "id": "roleConsiderationQ3", + "label": "How does this worker suit the role?" + } + ] + } + ] + }, + "footer": { + "type": "footer", + "children": [ + { + "enabled": "false", + "type": "richText" + } + ] + }, + "pageType": "EDIT" + }, + "outboundData": { + "outboundEndPoints": [ + { + "name": "storePromotionNominationBO", + "baseUrlType": "app", + "url": "promotionNominationBOS", + "httpMethod": "POST", + "authType": "sso", + "onSend": "<% + //Outbound endpoint that submits the BO + + + var obj = {:}; + + obj.add('nominee', (!empty selectedEmployeeWidget.selectedEntries[0].id) ? {'id':selectedEmployeeWidget.selectedEntries[0].id} : null); + obj.add('nominator', (!empty me.id) ? {'id':me.id} : null); + obj.add('nominationReason', (!empty promotionReasonWidget.selectedEntries[0].descriptor) ? promotionReasonWidget.selectedEntries[0].descriptor : null); + obj.add('proposedDate', (!empty proposedDateWidget.value) ? date:format(proposedDateWidget.value, 'yyyy-MM-dd') : null); + obj.add('proposedJobProfile', (!empty proposedJobProfileWidget.selectedEntries[0].id) ? {'id':proposedJobProfileWidget.selectedEntries[0].id} : null); + obj.add('promotionCycle', (!empty promotionCycleWidget.value) ? promotionCycleWidget.value : null); + obj.add('timeInJobProfile', (!empty timeJobProfileWidget.value) ? timeJobProfileWidget.value : null); + obj.add('hireDate', (!empty hireDateWidget.value) ? date:format(hireDateWidget.value, 'yyyy-MM-dd') : null); + obj.add('currentJobProfile', (!empty currentJobProfileWidget.selectedEntries[0].id) ? {'id':currentJobProfileWidget.selectedEntries[0].id} : null); + obj.add('currentJobTitle', (!empty currentJobTitleWidget.value) ? currentJobTitleWidget.value : null); + obj.add('lastPromotionDate', (!empty lastPromotionDateWidget.value) ? date:format(lastPromotionDateWidget.value, 'yyyy-MM-dd') : '2020-01-01'); + obj.add('workerConsideration', (!empty promotionConsiderationQ1.value) ? promotionConsiderationQ1.value : null); + obj.add('businessNeed', (!empty promotionBusNeedQ2.value) ? promotionBusNeedQ2.value : null); + obj.add('workerSuitRole', (!empty roleConsiderationQ3.value) ? roleConsiderationQ3.value : null); + self.data = obj; + console.info('Nomination payload is ' + json:asJSON(self.data)); + return self.data; + %>", + "failOnStatusCodes": [ + { + "code": 400 + }, + { + "code": 403 + } + ] + }, + { + "name": "submitPromotion", + "baseUrlType": "app", + "url": "<% 'https://api.workday.com/apps/promotionNomination_rvylxm/v1/promotionNominationBPEvents' %>", + "authType": "sso", + "onSend": "<% + var payload = + { + 'description': 'Approval for Promotion Nomination', + 'businessProcessTarget': {'id': storePromotionNominationBO.id} + }; + console.info('zzzzzzzzzzz ' + payload.businessProcessTarget); + return payload; + %>", + "failOnStatusCodes": [ + { + "code": 400 + }, + { + "code": 403 + } + ] + }, + { + "type": "outboundVariable", + "name": "ExtensionResponse", + "variableScope": "flow", + "values": [ + { + "outboundPath": "PromotionSubmissionResponseValue", + "value": "<% submitPromotion.id %>" + } + ] + } + ] + }, + "securityDomains": [ + "ManagerPromotionNomination" + ] +} \ No newline at end of file diff --git a/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.amd b/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.amd new file mode 100644 index 0000000..730aa59 --- /dev/null +++ b/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.amd @@ -0,0 +1,42 @@ +{ + "appProperties": [ ], + "tasks": [ + { + "id": "managerNomination", + "routingPattern": "/", + "page": { + "id": "managerNomination" + } + }, + { + "id": "eventDetails", + "routingPattern": "/eventDetails/{eventId}", + "page": { + "id": "eventDetails" + } + } + ], + "applicationId": "promotionNomination_rvylxm", + "dataProviders": [ + { + "key": "workday-staffing", + "value": "https://api.workday.com/staffing/v7/" + }, + { + "key": "workday-wql", + "value": "https://api.us.wcp.workday.com/wql/v1" + }, + { + "key": "workday-common", + "value": "https://api.us.wcp.workday.com/common/v1" + }, + { + "key": "workday-bp", + "value": "https://api.workday.com/businessProcess/v1/" + }, + { + "key": "app", + "value": "https://api.workday.com/apps/promotionNomination_rvylxm/v1/" + } + ] +} \ No newline at end of file diff --git a/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.smd b/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.smd new file mode 100644 index 0000000..2137d71 --- /dev/null +++ b/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.smd @@ -0,0 +1,21 @@ +{ + "id": "promotionNomination_rvylxm", + "languages": [ + { + "code": "en-US", + "description": "English" + } + ], + "siteAuth": { + "authTypes": [ + { + "scheme": "SSO", + "id": "sso" + } + ] + }, + "siteId": "promotionNomination_rvylxm", + "cdnEnabled": true, + "siteProperties": [ ], + "applicationId": "promotionNomination_rvylxm" +} \ No newline at end of file From 66f4514ccfe4e652c33fc2f2764df62d51d15bec Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Tue, 8 Sep 2026 19:53:47 -0400 Subject: [PATCH 06/17] Add README for Promotion Nomination App The README provides an overview of the Promotion Nomination App, detailing its features, workflow, and optional enhancements. --- examples/Promotion_Nomination/README.md | 59 +++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 examples/Promotion_Nomination/README.md diff --git a/examples/Promotion_Nomination/README.md b/examples/Promotion_Nomination/README.md new file mode 100644 index 0000000..65fd760 --- /dev/null +++ b/examples/Promotion_Nomination/README.md @@ -0,0 +1,59 @@ +

Promotion Nomination App

+ +

+ A streamlined promotion nomination platform that enables managers to identify, evaluate, and advocate for top-performing direct reports. +

+ +
+ +

📋 Overview

+

+ The Promotion Nomination App automates the collection of employee career data and routes nominations through a multi-level approval workflow, ensuring consistent evaluation, transparency, and governance across all promotion decisions. +

+ +

✨ Key Features

+
    +
  • 👤 Employee Selection: Managers easily nominate from their direct reports via an intuitive dropdown interface.
  • +
  • ⚡ Auto-Populated Career Data: The system automatically retrieves current job profile, tenure, hire date, and promotion history. Optionally, you can enhance it to retrieve worker Talent details from Workday or any 3rd platform
  • +
  • 📝 Structured Business Case: Guided fields capture detailed nomination rationale and alignment with target roles.
  • +
  • 📅 Promotion Cycle Tracking: Tag nominations to specific evaluation cycles (e.g., 2026-Q1).
  • +
  • 🔄 Approval Workflow: Automatic routing to next-level managers, followed by the People Business Partner (PBP).
  • +
  • 🔒 Audit Trail: All records are securely stored in a Custom Business Object (CBO) for governance, tracking, and analytics.
  • +
+ +

⚙️ How It Works

+
    +
  1. + Select Employee
    + Manager selects an eligible worker from their list of direct reports. +
  2. +
  3. + Auto-Populate Career History
    + The system automatically pulls key worker details: +
      +
    • Current job profile & time in position
    • +
    • Original hire date
    • +
    • Last promotion date
    • +
    +
  4. +
  5. + Build the Rationale
    + Manager provides promotion justification: +
      +
    • Reason for Promotion: Merit, increased responsibilities, or restructuring
    • +
    • Target Role: Proposed job profile
    • +
    • Timeline: Proposed effective date
    • +
    • Business Impact: Detailed justification field
    • +
    +
  6. +
  7. + Approval & Archival
    + The nomination enters the multi-level approval chain. Once approved, all data is archived to the Custom Business Object. +
  8. +
+ +

💡 Optional Enhancements

+
+ Workday Orchestrate Integration:
+ The app can be configured to automatically trigger a Change Job business process for the worker upon final approval completion using a Workday Orchestrate workflow. +
From c4c1d3114b7f5ae80377da00bdf98cd52274899f Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Tue, 8 Sep 2026 19:59:39 -0400 Subject: [PATCH 07/17] Add artifacts section and optional enhancements to README --- examples/Promotion_Nomination/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/examples/Promotion_Nomination/README.md b/examples/Promotion_Nomination/README.md index 65fd760..bcfded4 100644 --- a/examples/Promotion_Nomination/README.md +++ b/examples/Promotion_Nomination/README.md @@ -51,7 +51,10 @@ The nomination enters the multi-level approval chain. Once approved, all data is archived to the Custom Business Object. - +

Artifacts

+
    +
  • managerNomination: Landing page for managers
  • +
  • eventDetails: Business process approval page definition
  • 💡 Optional Enhancements

    Workday Orchestrate Integration:
    From ce7fab6fbed2072093b408f2d0a5aec9f6f069a4 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Wed, 16 Sep 2026 17:10:03 -0400 Subject: [PATCH 08/17] Add failOnStatusCodes to eventDetails.pmd --- .../presentation/eventDetails.pmd | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/examples/Promotion_Nomination/presentation/eventDetails.pmd b/examples/Promotion_Nomination/presentation/eventDetails.pmd index 4ded9fc..99c7ff3 100644 --- a/examples/Promotion_Nomination/presentation/eventDetails.pmd +++ b/examples/Promotion_Nomination/presentation/eventDetails.pmd @@ -1,16 +1,21 @@ { "id": "eventDetails", +"securityDomains": [ + "ManagerPromotionNomination" + ], "endPoints": [ { "name": "eventGenericBP", "url": "<% 'https://api.workday.com/businessProcess/v1/events/' + queryParams.eventId %>", - "authType": "sso" + "authType": "sso", +"failOnStatusCodes": [{"code": 400}, {"code": 403}] }, { "name": "getPromotionNominationBP", "url": "<% 'https://api.workday.com/apps/'+ site.applicationId + '/v1/promotionNominationBOS/' + eventGenericBP.for.id%>", "authType": "sso", - "httpMethod": "GET" + "httpMethod": "GET", +"failOnStatusCodes": [{"code": 400}, {"code": 403}] } ], "presentation": { @@ -135,8 +140,5 @@ ] }, "pageType": "VIEW" - }, - "securityDomains": [ - "ManagerPromotionNomination" - ] -} \ No newline at end of file + } +} From 65f43c13763963ceb46cb3bae0a28038871dffe3 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Wed, 16 Sep 2026 22:20:30 -0400 Subject: [PATCH 09/17] Update app-info.json for Promotion Nomination --- examples/Promotion_Nomination/app-info.json | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/Promotion_Nomination/app-info.json b/examples/Promotion_Nomination/app-info.json index c371409..68bed35 100644 --- a/examples/Promotion_Nomination/app-info.json +++ b/examples/Promotion_Nomination/app-info.json @@ -1,4 +1,3 @@ -JSON { "title": "Promotion Nomination", "description": "Workday App for managers to nominate their direct reports for promotions", From 67bb081bd263023c58caf5ee96998ec8128f1c51 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Wed, 16 Sep 2026 22:30:52 -0400 Subject: [PATCH 10/17] Enhance managerNomination.pmd with error handling Updated managerNomination.pmd to include failOnStatusCodes for endpoints, modified query syntax, and adjusted outbound data structure. --- .../presentation/managerNomination.pmd | 219 +++++++++--------- 1 file changed, 114 insertions(+), 105 deletions(-) diff --git a/examples/Promotion_Nomination/presentation/managerNomination.pmd b/examples/Promotion_Nomination/presentation/managerNomination.pmd index e7caec4..5ce0968 100644 --- a/examples/Promotion_Nomination/presentation/managerNomination.pmd +++ b/examples/Promotion_Nomination/presentation/managerNomination.pmd @@ -1,60 +1,143 @@ { "id": "managerNomination", + "securityDomains": [ + "ManagerPromotionNomination" + ], "endPoints": [ { "name": "me", "baseUrlType": "workday-staffing", "url": "/workers/me", - "authType": "sso" + "authType": "sso", + "failOnStatusCodes": [{"code": 400}, {"code": 403}] }, - { - "_comment": "Retrieves logged-in manager's direct reports ", - "name": "getEmployeeList", + { "_comment": "Retrieves logged-in manager's direct reports ", + "name": "getEmployeeList", "baseUrlType": "workday-wql", "authType": "sso", "url": "<% - var query= '/data?query=' + string:urlEncode('SELECT worker FROM myDirectReports WHERE workerType in (d588c41a446c11de98360015c5e6daf6)'); + let query= `/data?query={{string:urlEncode'SELECT worker FROM myDirectReports WHERE workerType in (d588c41a446c11de98360015c5e6daf6)'}}` return query; - %>" + %>", + "failOnStatusCodes": [{"code": 400}, {"code": 403}] }, { "name": "workerInfo", - "url": "https://api.workday.com/common/v1/workers/me", - "authType": "sso" - }, - { - "_comment": "Retrieves selected worker information ", - "deferred": true, - "name": "getEmployeeData", - "baseUrlType": "workday-wql", + "baseUrlType": "workday-common", + "url": "/workers/me", "authType": "sso", - "url": "<% - var query= '/data?query=' + string:urlEncode('SELECT worker, location, manager_Level01, hireDate, timeInJobProfile, jobProfile, jobTitle, lastPromotionDate FROM myDirectReports WHERE worker in \"' +selectedWorkerIdQuery+ '\"'); - return query; - %>" + "failOnStatusCodes": [{"code": 400}, {"code": 403}] }, + { + "_comment": "Retrieves selected worker information", + "deferred": true, + "name": "getEmployeeData", + "baseUrlType": "workday-wql", + "authType": "sso", + "url": "<% return '/data?query=' + string:urlEncode(`SELECT worker, location, manager_Level01, hireDate, timeInJobProfile, jobProfile, jobTitle, lastPromotionDate FROM myDirectReports WHERE worker in \"{{selectedWorkerIdQuery}}\"`); %>", + "failOnStatusCodes": [{"code": 400}, {"code": 403}] +}, { "name": "getJobProfiles", "baseUrlType": "workday-wql", "authType": "sso", "url": "<% - var query= '/data?query=' + string:urlEncode('SELECT jobProfileName, workdayID FROM allActiveJobProfiles (dataSourceFilter = defaultFilter) WHERE jobProfileName startswith \"' +instanceListQuery+ '\"'); + let query= '/data?query=' + string:urlEncode(`SELECT jobProfileName, workdayID FROM allActiveJobProfiles (dataSourceFilter = defaultFilter) WHERE jobProfileName startswith \"{{instanceListQuery}}\"`); // console.info('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXz', query); return query.replace('%2B','%20'); %>", - "deferred": true + "deferred": true, + "failOnStatusCodes": [{"code": 400}, {"code": 403}] }, { "name": "getJobProfilesNoSearch", "baseUrlType": "workday-wql", "authType": "sso", "url": "<% - var query= '/data?query=' + string:urlEncode('SELECT jobProfileName, workdayID FROM allActiveJobProfiles (dataSourceFilter = defaultFilter)'); + const query= `/data?query={{string:urlEncode'SELECT jobProfileName, workdayID FROM allActiveJobProfiles (dataSourceFilter = defaultFilter)'}}`; // console.info('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXz', query); return query.replace('%2B','%20'); - %>" + %>", + "failOnStatusCodes": [{"code": 400}, {"code": 403}] } ], + "outboundData": { + "outboundEndPoints": [ + { + "name": "storePromotionNominationBO", + "baseUrlType": "app", + "url": "promotionNominationBOS", + "httpMethod": "POST", + "authType": "sso", + "onSend": "<% + //Outbound endpoint that submits the BO + + + let obj = {:}; + + obj.add('nominee', (!empty selectedEmployeeWidget.selectedEntries[0].id) ? {'id':selectedEmployeeWidget.selectedEntries[0].id} : null); + obj.add('nominator', (!empty me.id) ? {'id':me.id} : null); + obj.add('nominationReason', (!empty promotionReasonWidget.selectedEntries[0].descriptor) ? promotionReasonWidget.selectedEntries[0].descriptor : null); + obj.add('proposedDate', (!empty proposedDateWidget.value) ? date:format(proposedDateWidget.value, 'yyyy-MM-dd') : null); + obj.add('proposedJobProfile', (!empty proposedJobProfileWidget.selectedEntries[0].id) ? {'id':proposedJobProfileWidget.selectedEntries[0].id} : null); + obj.add('promotionCycle', (!empty promotionCycleWidget.value) ? promotionCycleWidget.value : null); + obj.add('timeInJobProfile', (!empty timeJobProfileWidget.value) ? timeJobProfileWidget.value : null); + obj.add('hireDate', (!empty hireDateWidget.value) ? date:format(hireDateWidget.value, 'yyyy-MM-dd') : null); + obj.add('currentJobProfile', (!empty currentJobProfileWidget.selectedEntries[0].id) ? {'id':currentJobProfileWidget.selectedEntries[0].id} : null); + obj.add('currentJobTitle', (!empty currentJobTitleWidget.value) ? currentJobTitleWidget.value : null); + obj.add('lastPromotionDate', (!empty lastPromotionDateWidget.value) ? date:format(lastPromotionDateWidget.value, 'yyyy-MM-dd') : '2020-01-01'); + obj.add('workerConsideration', (!empty promotionConsiderationQ1.value) ? promotionConsiderationQ1.value : null); + obj.add('businessNeed', (!empty promotionBusNeedQ2.value) ? promotionBusNeedQ2.value : null); + obj.add('workerSuitRole', (!empty roleConsiderationQ3.value) ? roleConsiderationQ3.value : null); + self.data = obj; + + return self.data; + %>", + "failOnStatusCodes": [ + { + "code": 400 + }, + { + "code": 403 + } + ] + }, + { + "name": "submitPromotion", + "baseUrlType": "app", + "url": "<% 'promotionNominationBPEvents' %>", + "authType": "sso", + "onSend": "<% + let payload = + { + 'description': 'Approval for Promotion Nomination', + 'businessProcessTarget': {'id': storePromotionNominationBO.id} + }; + //console.info('zzzzzzzzzzz ' + payload.businessProcessTarget); + return payload; + %>", + "failOnStatusCodes": [ + { + "code": 400 + }, + { + "code": 403 + } + ] + }, + { + "type": "outboundVariable", + "name": "ExtensionResponse", + "variableScope": "flow", + "values": [ + { + "outboundPath": "PromotionSubmissionResponseValue", + "value": "<% submitPromotion.id %>" + } + ] + } + ] + }, "presentation": { "title": { "type": "title", @@ -62,10 +145,12 @@ }, "body": { "type": "fieldSet", + "id": "fieldSetVertical", "horizontal": false, "children": [ { "type": "section", + "id": "section1", "children": [ { "type": "readOnlyText", @@ -75,6 +160,7 @@ { "horizontal": true, "type": "section", + "id": "section2", "verticalAlignment": "top", "children": [ { @@ -189,7 +275,7 @@ "label": "Promotion Cycle", "type": "text", "id": "promotionCycleWidget", - "value": "2026-Q1" + "value": "<% return date:year([TODAY_DATE]).toString(); %>" }, { "enabled": false, @@ -262,93 +348,16 @@ }, "footer": { "type": "footer", + "id": "footerTextID", "children": [ { - "enabled": "false", + "enabled": false, "type": "richText" } ] }, "pageType": "EDIT" - }, - "outboundData": { - "outboundEndPoints": [ - { - "name": "storePromotionNominationBO", - "baseUrlType": "app", - "url": "promotionNominationBOS", - "httpMethod": "POST", - "authType": "sso", - "onSend": "<% - //Outbound endpoint that submits the BO - - - var obj = {:}; + } + - obj.add('nominee', (!empty selectedEmployeeWidget.selectedEntries[0].id) ? {'id':selectedEmployeeWidget.selectedEntries[0].id} : null); - obj.add('nominator', (!empty me.id) ? {'id':me.id} : null); - obj.add('nominationReason', (!empty promotionReasonWidget.selectedEntries[0].descriptor) ? promotionReasonWidget.selectedEntries[0].descriptor : null); - obj.add('proposedDate', (!empty proposedDateWidget.value) ? date:format(proposedDateWidget.value, 'yyyy-MM-dd') : null); - obj.add('proposedJobProfile', (!empty proposedJobProfileWidget.selectedEntries[0].id) ? {'id':proposedJobProfileWidget.selectedEntries[0].id} : null); - obj.add('promotionCycle', (!empty promotionCycleWidget.value) ? promotionCycleWidget.value : null); - obj.add('timeInJobProfile', (!empty timeJobProfileWidget.value) ? timeJobProfileWidget.value : null); - obj.add('hireDate', (!empty hireDateWidget.value) ? date:format(hireDateWidget.value, 'yyyy-MM-dd') : null); - obj.add('currentJobProfile', (!empty currentJobProfileWidget.selectedEntries[0].id) ? {'id':currentJobProfileWidget.selectedEntries[0].id} : null); - obj.add('currentJobTitle', (!empty currentJobTitleWidget.value) ? currentJobTitleWidget.value : null); - obj.add('lastPromotionDate', (!empty lastPromotionDateWidget.value) ? date:format(lastPromotionDateWidget.value, 'yyyy-MM-dd') : '2020-01-01'); - obj.add('workerConsideration', (!empty promotionConsiderationQ1.value) ? promotionConsiderationQ1.value : null); - obj.add('businessNeed', (!empty promotionBusNeedQ2.value) ? promotionBusNeedQ2.value : null); - obj.add('workerSuitRole', (!empty roleConsiderationQ3.value) ? roleConsiderationQ3.value : null); - self.data = obj; - console.info('Nomination payload is ' + json:asJSON(self.data)); - return self.data; - %>", - "failOnStatusCodes": [ - { - "code": 400 - }, - { - "code": 403 - } - ] - }, - { - "name": "submitPromotion", - "baseUrlType": "app", - "url": "<% 'https://api.workday.com/apps/promotionNomination_rvylxm/v1/promotionNominationBPEvents' %>", - "authType": "sso", - "onSend": "<% - var payload = - { - 'description': 'Approval for Promotion Nomination', - 'businessProcessTarget': {'id': storePromotionNominationBO.id} - }; - console.info('zzzzzzzzzzz ' + payload.businessProcessTarget); - return payload; - %>", - "failOnStatusCodes": [ - { - "code": 400 - }, - { - "code": 403 - } - ] - }, - { - "type": "outboundVariable", - "name": "ExtensionResponse", - "variableScope": "flow", - "values": [ - { - "outboundPath": "PromotionSubmissionResponseValue", - "value": "<% submitPromotion.id %>" - } - ] - } - ] - }, - "securityDomains": [ - "ManagerPromotionNomination" - ] -} \ No newline at end of file +} From 8b8213d9cf2411a0eff4af2be79c7e4d45ade8e7 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Wed, 16 Sep 2026 22:31:18 -0400 Subject: [PATCH 11/17] Refactor API endpoints in promotionNomination_rvylxm --- .../presentation/promotionNomination_rvylxm.amd | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.amd b/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.amd index 730aa59..a5a69ce 100644 --- a/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.amd +++ b/examples/Promotion_Nomination/presentation/promotionNomination_rvylxm.amd @@ -1,5 +1,5 @@ { - "appProperties": [ ], + "appProperties": [], "tasks": [ { "id": "managerNomination", @@ -16,27 +16,27 @@ } } ], - "applicationId": "promotionNomination_rvylxm", + "applicationId": site.applicationId, "dataProviders": [ { "key": "workday-staffing", - "value": "https://api.workday.com/staffing/v7/" + "value": "<% apiGatewayEndpoint + '/staffing/v7/' %>" }, { "key": "workday-wql", - "value": "https://api.us.wcp.workday.com/wql/v1" + "value": "<% apiGatewayEndpoint + '/wql/v1' %>" }, { "key": "workday-common", - "value": "https://api.us.wcp.workday.com/common/v1" + "value": "<% apiGatewayEndpoint + '/common/v1' %>" }, { "key": "workday-bp", - "value": "https://api.workday.com/businessProcess/v1/" + "value": "<% apiGatewayEndpoint + '/businessProcess/v1/' %>" }, { "key": "app", - "value": "https://api.workday.com/apps/promotionNomination_rvylxm/v1/" + "value": "<% apiGatewayEndpoint + '/apps/promotionNomination_rvylxm/v1/' %>" } ] -} \ No newline at end of file +} From e77b30c2bb8afec40e540f13bd8432275de15f68 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Wed, 16 Sep 2026 22:36:23 -0400 Subject: [PATCH 12/17] Refactor eventDetails.pmd for URL formatting --- .../presentation/eventDetails.pmd | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/examples/Promotion_Nomination/presentation/eventDetails.pmd b/examples/Promotion_Nomination/presentation/eventDetails.pmd index 99c7ff3..0ad41d2 100644 --- a/examples/Promotion_Nomination/presentation/eventDetails.pmd +++ b/examples/Promotion_Nomination/presentation/eventDetails.pmd @@ -1,21 +1,23 @@ { "id": "eventDetails", -"securityDomains": [ + "securityDomains": [ "ManagerPromotionNomination" ], "endPoints": [ { "name": "eventGenericBP", - "url": "<% 'https://api.workday.com/businessProcess/v1/events/' + queryParams.eventId %>", + "baseUrlType": "workday-bp", + "url": "<% `events/{{queryParams.eventId}}` %>", "authType": "sso", -"failOnStatusCodes": [{"code": 400}, {"code": 403}] + "failOnStatusCodes": [{"code": 400}, {"code": 403}] }, { "name": "getPromotionNominationBP", - "url": "<% 'https://api.workday.com/apps/'+ site.applicationId + '/v1/promotionNominationBOS/' + eventGenericBP.for.id%>", + "baseUrlType": "app", + "url": "<% `promotionNominationBOS/{{eventGenericBP.for.id}}` %>", "authType": "sso", "httpMethod": "GET", -"failOnStatusCodes": [{"code": 400}, {"code": 403}] + "failOnStatusCodes": [{"code": 400}, {"code": 403}] } ], "presentation": { @@ -25,6 +27,7 @@ }, "body": { "type": "section", + "id": "sectionID1", "horizontal": false, "children": [ { @@ -43,6 +46,7 @@ }, { "type": "fieldSet", + "id": "fieldSet1", "children": [ { "type": "text", @@ -134,11 +138,13 @@ "children": [ { "type": "richText", - "enabled": "false", + "id": "footerTextID", + "enabled": false, "value": "Powered By Workday Extend" } ] }, "pageType": "VIEW" } + } From 2b9c3c856a2b03ac7ba21e81067317c762ea816c Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Thu, 17 Sep 2026 09:40:24 -0400 Subject: [PATCH 13/17] Update README with deployment and integration details Added optional enhancements and deployment instructions. --- examples/Promotion_Nomination/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/Promotion_Nomination/README.md b/examples/Promotion_Nomination/README.md index bcfded4..795b92f 100644 --- a/examples/Promotion_Nomination/README.md +++ b/examples/Promotion_Nomination/README.md @@ -56,6 +56,9 @@
  • managerNomination: Landing page for managers
  • eventDetails: Business process approval page definition
  • 💡 Optional Enhancements

    + + ##before you Deploy: + Make sure the app base URL is updated in the AMD file with your app name.
    Workday Orchestrate Integration:
    The app can be configured to automatically trigger a Change Job business process for the worker upon final approval completion using a Workday Orchestrate workflow. From 1d426dd2b7d9083d14f3159b3a6c55e4684e6429 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Thu, 17 Sep 2026 15:51:14 -0400 Subject: [PATCH 14/17] Refactor README for Promotion Nomination App Updated the README to improve clarity and structure, including sections on usage and key capabilities. --- examples/Promotion_Nomination/README.md | 102 ++++++++++-------------- 1 file changed, 43 insertions(+), 59 deletions(-) diff --git a/examples/Promotion_Nomination/README.md b/examples/Promotion_Nomination/README.md index 795b92f..482dd88 100644 --- a/examples/Promotion_Nomination/README.md +++ b/examples/Promotion_Nomination/README.md @@ -1,65 +1,49 @@ -

    Promotion Nomination App

    +# Promotion Nomination App -

    - A streamlined promotion nomination platform that enables managers to identify, evaluate, and advocate for top-performing direct reports. -

    +A streamlined promotion nomination platform that enables managers to identify, evaluate, and advocate for top-performing direct reports. -
    +## What it is -

    📋 Overview

    -

    - The Promotion Nomination App automates the collection of employee career data and routes nominations through a multi-level approval workflow, ensuring consistent evaluation, transparency, and governance across all promotion decisions. -

    +The Promotion Nomination App automates the collection of employee career data and routes nominations through a multi-level approval workflow. It ensures consistent evaluation, transparency, and governance across all promotion decisions by handling everything from employee selection through final approval and archival. -

    ✨ Key Features

    -
      -
    • 👤 Employee Selection: Managers easily nominate from their direct reports via an intuitive dropdown interface.
    • -
    • ⚡ Auto-Populated Career Data: The system automatically retrieves current job profile, tenure, hire date, and promotion history. Optionally, you can enhance it to retrieve worker Talent details from Workday or any 3rd platform
    • -
    • 📝 Structured Business Case: Guided fields capture detailed nomination rationale and alignment with target roles.
    • -
    • 📅 Promotion Cycle Tracking: Tag nominations to specific evaluation cycles (e.g., 2026-Q1).
    • -
    • 🔄 Approval Workflow: Automatic routing to next-level managers, followed by the People Business Partner (PBP).
    • -
    • 🔒 Audit Trail: All records are securely stored in a Custom Business Object (CBO) for governance, tracking, and analytics.
    • -
    +## What's inside -

    ⚙️ How It Works

    -
      -
    1. - Select Employee
      - Manager selects an eligible worker from their list of direct reports. -
    2. -
    3. - Auto-Populate Career History
      - The system automatically pulls key worker details: -
        -
      • Current job profile & time in position
      • -
      • Original hire date
      • -
      • Last promotion date
      • -
      -
    4. -
    5. - Build the Rationale
      - Manager provides promotion justification: -
        -
      • Reason for Promotion: Merit, increased responsibilities, or restructuring
      • -
      • Target Role: Proposed job profile
      • -
      • Timeline: Proposed effective date
      • -
      • Business Impact: Detailed justification field
      • -
      -
    6. -
    7. - Approval & Archival
      - The nomination enters the multi-level approval chain. Once approved, all data is archived to the Custom Business Object. -
    8. -
    -

    Artifacts

    -
      -
    • managerNomination: Landing page for managers
    • -
    • eventDetails: Business process approval page definition
    • -

      💡 Optional Enhancements

      +**Core components:** +- **managerNomination**: Landing page where managers submit and track nominations +- **eventDetails**: Business process approval page definition for multi-level review - ##before you Deploy: - Make sure the app base URL is updated in the AMD file with your app name. -
      - Workday Orchestrate Integration:
      - The app can be configured to automatically trigger a Change Job business process for the worker upon final approval completion using a Workday Orchestrate workflow. -
      +**Key capabilities:** +- Employee selection from direct reports with intuitive dropdown interface +- Auto-populated career data (current job profile, tenure, hire date, promotion history) +- Optional integration with Workday Talent details or third-party platforms +- Structured fields for nomination rationale and target role alignment +- Promotion cycle tracking (e.g., 2026-Q1) +- Multi-level approval routing to next-level managers and People Business Partner +- Secure storage and audit trail via Custom Business Object + +## How to use it + +**1. Select Employee** +Manager selects an eligible worker from their list of direct reports. + +**2. Auto-Populate Career History** +The system automatically pulls: +- Current job profile and time in position +- Original hire date +- Last promotion date + +**3. Build the Nomination** +Manager provides promotion justification with: +- Reason for promotion (merit, increased responsibilities, restructuring) +- Target role (proposed job profile) +- Timeline (proposed effective date) +- Business impact statement + +**4. Route Through Approvals** +The nomination enters the multi-level approval chain. Once all approvals are granted, data is archived to the Custom Business Object. + +## Before you deploy + +- Update the app base URL in the AMD file with your app name +- Optionally configure Workday Orchestrate integration to automatically trigger the Change Job business process upon final approval +- Test the approval workflow with test users at each level From 54c9c0704ba65b7c0caf97836a8eac8613d0f1d7 Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Thu, 17 Sep 2026 15:51:54 -0400 Subject: [PATCH 15/17] Rename app-info.json to example.json --- examples/Promotion_Nomination/{app-info.json => example.json} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/Promotion_Nomination/{app-info.json => example.json} (100%) diff --git a/examples/Promotion_Nomination/app-info.json b/examples/Promotion_Nomination/example.json similarity index 100% rename from examples/Promotion_Nomination/app-info.json rename to examples/Promotion_Nomination/example.json From 73fe0326625a1002b47bace8841f1e4d6ea18d2f Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Thu, 17 Sep 2026 15:52:53 -0400 Subject: [PATCH 16/17] Fix footer ID in managerNomination.pmd --- .../Promotion_Nomination/presentation/managerNomination.pmd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/Promotion_Nomination/presentation/managerNomination.pmd b/examples/Promotion_Nomination/presentation/managerNomination.pmd index 5ce0968..c64c06b 100644 --- a/examples/Promotion_Nomination/presentation/managerNomination.pmd +++ b/examples/Promotion_Nomination/presentation/managerNomination.pmd @@ -348,11 +348,12 @@ }, "footer": { "type": "footer", - "id": "footerTextID", + "id": "footerID", "children": [ { "enabled": false, - "type": "richText" + "type": "richText", + "id": "footerTextID" } ] }, From ccb27e134e0696a216e2c33dec572e2d9a04c6cb Mon Sep 17 00:00:00 2001 From: abhi-matti Date: Thu, 17 Sep 2026 15:57:48 -0400 Subject: [PATCH 17/17] Rename README.md file for promotion nomination --- examples/{Promotion_Nomination => promotion-nomination}/README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{Promotion_Nomination => promotion-nomination}/README.md (100%) diff --git a/examples/Promotion_Nomination/README.md b/examples/promotion-nomination/README.md similarity index 100% rename from examples/Promotion_Nomination/README.md rename to examples/promotion-nomination/README.md